From c7f78f4277c139bfe3bfa1cefa2ad344b5efd6af Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 13 Jun 2026 16:32:10 -0700 Subject: [PATCH 1/2] =?UTF-8?q?chore(ci):=20supply-chain=20hardening=20?= =?UTF-8?q?=E2=80=94=20SHA-pin=20actions,=20dependabot,=20deploy=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hardens the public repo's CI/CD ahead of beta traffic. - SHA-pin every third-party and first-party action across all workflows (was using mutable tags / @latest). Notably webfactory/ssh-agent (holds the VPS deploy key), anthropics/claude-code-action, codecov/codecov-action, and anomalyco/opencode (was @latest, a moving ref). Version kept in a trailing comment for readability. - Add .github/dependabot.yml (github-actions + pip + npm, weekly, grouped) so the new pins receive security/patch bumps instead of going stale. - Re-enable the test gate on the production deploy job (was commented out, so production could deploy without tests passing); clarify the staging gate. - Delete opencode-review.yml: it was already disabled (`if: false`) and flagged by its own comment as leaking GITHUB_TOKEN into PR comments, yet still carried issues:write + pull-requests:write. Removed rather than left parked. Settings applied out of band: Dependabot vulnerability alerts + automated security fixes enabled; branch protection on main set to strict (require up-to-date branch) + required conversation resolution. --- .github/dependabot.yml | 31 ++++++ .github/workflows/claude-code-review.yml | 4 +- .github/workflows/claude.yml | 4 +- .github/workflows/deploy.yml | 12 +-- .github/workflows/lifecycle.yml | 8 +- .github/workflows/opencode-review.yml | 116 ----------------------- .github/workflows/opencode.yml | 4 +- .github/workflows/test.yml | 38 ++++---- 8 files changed, 66 insertions(+), 151 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/opencode-review.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..adcb1e3b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,31 @@ +version: 2 +updates: + # Keep GitHub Actions SHA pins current (security patches to pinned actions). + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + actions: + patterns: ["*"] + update-types: [minor, patch] + + # Python dependencies (pyproject.toml). + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + python-minor-patch: + update-types: [minor, patch] + + # Web UI dependencies. + - package-ecosystem: npm + directory: /web-ui + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + npm-minor-patch: + update-types: [minor, patch] diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index c0be2d42..68bbeff8 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -33,7 +33,7 @@ jobs: if: | github.event.pull_request.changed_files >= 5 || steps.calc.outputs.total >= 20 - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 1 @@ -43,7 +43,7 @@ jobs: github.event.pull_request.changed_files >= 5 || steps.calc.outputs.total >= 20 id: claude-review - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@d5726de019ec4498aa667642bc3a80fca83aa102 # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} prompt: | diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 412cef9e..67c34ad5 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -26,13 +26,13 @@ jobs: actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 1 - name: Run Claude Code id: claude - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@d5726de019ec4498aa667642bc3a80fca83aa102 # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4064d9f3..442b8bf0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -34,7 +34,7 @@ jobs: deploy-staging: name: Deploy to Staging runs-on: ubuntu-latest - needs: test # Temporarily disabled for debugging + needs: test # Gate: do not deploy unless the test suite passes if: | (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging') @@ -44,10 +44,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up SSH - uses: webfactory/ssh-agent@v0.9.0 + uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 with: ssh-private-key: ${{ secrets.SSH_KEY }} @@ -248,7 +248,7 @@ jobs: deploy-production: name: Deploy to Production runs-on: ubuntu-latest - # needs: test # Temporarily disabled for debugging + needs: test # Gate: do not deploy to production unless the test suite passes if: | (github.event_name == 'release') || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production') @@ -258,10 +258,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up SSH - uses: webfactory/ssh-agent@v0.9.0 + uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 with: ssh-private-key: ${{ secrets.SSH_KEY }} diff --git a/.github/workflows/lifecycle.yml b/.github/workflows/lifecycle.yml index 8fcafd50..5d0bf97b 100644 --- a/.github/workflows/lifecycle.yml +++ b/.github/workflows/lifecycle.yml @@ -35,15 +35,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4 with: enable-cache: true @@ -88,7 +88,7 @@ jobs: - name: Upload test artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: lifecycle-failure-${{ github.run_id }} path: | diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml deleted file mode 100644 index 06bef5bf..00000000 --- a/.github/workflows/opencode-review.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: OpenCode PR Review - -on: - pull_request: - types: [opened, synchronize] - # Skip review for documentation and config-only changes - # Exclude this workflow file to prevent self-triggering loops - paths-ignore: - - "**/*.md" - - ".github/workflows/opencode-review.yml" - - ".gitignore" - - "pyproject.toml" - -# Cancel in-progress runs for the same PR to avoid duplicate reviews -concurrency: - group: opencode-review-${{ github.event.pull_request.number }} - cancel-in-progress: true - -jobs: - opencode-review: - if: false # Disabled - leaks environment variables including GITHUB_TOKEN into PR comments - runs-on: ubuntu-latest - timeout-minutes: 10 # Prevent hanging - kill after 10 min - permissions: - id-token: write - contents: read - pull-requests: write - issues: write - - steps: - - name: Calculate total changes - id: calc - run: | - additions=${{ github.event.pull_request.additions }} - deletions=${{ github.event.pull_request.deletions }} - total=$((additions + deletions)) - echo "total=$total" >> $GITHUB_OUTPUT - - - name: Checkout repository - # Only review substantial changes (5+ files OR 20+ lines changed) - if: | - github.event.pull_request.changed_files >= 5 || - steps.calc.outputs.total >= 20 - uses: actions/checkout@v6 - with: - fetch-depth: 1 - persist-credentials: false - - - name: Clear git credentials to avoid duplicate auth - if: | - github.event.pull_request.changed_files >= 5 || - steps.calc.outputs.total >= 20 - run: | - # Clear all GitHub-related git config to prevent auth conflicts - git config --global --unset-all http.https://github.com/.extraheader || true - git config --local --unset-all http.https://github.com/.extraheader || true - git config --global --unset-all credential.helper || true - git config --local --unset-all credential.helper || true - git config --global --unset-all credential."https://github.com".helper || true - git config --local --unset-all credential."https://github.com".helper || true - # Remove any credential URLs - git config --global --unset-all credential.url || true - git config --local --unset-all credential.url || true - # Clear any includeIf configs that might add credentials - # Note: git config doesn't support wildcards, so we iterate over matching keys - # Use case-insensitive grep to catch both "includeIf" and "includeif" - for key in $(git config --global --list --name-only 2>/dev/null | grep -i "^includeif\." || true); do - git config --global --unset "$key" || true - done - for key in $(git config --local --list --name-only 2>/dev/null | grep -i "^includeif\." || true); do - git config --local --unset "$key" || true - done - - - name: Run OpenCode PR Review - # Only review substantial changes (5+ files OR 20+ lines changed) - if: | - github.event.pull_request.changed_files >= 5 || - steps.calc.outputs.total >= 20 - uses: anomalyco/opencode/github@latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }} - # Pass PR context as environment variables for the review - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_TITLE: ${{ github.event.pull_request.title }} - PR_BODY: ${{ github.event.pull_request.body }} - REPO_NAME: ${{ github.repository }} - with: - model: zai-coding-plan/glm-4.7 - use_github_token: true - prompt: | - You are reviewing PR #${{ github.event.pull_request.number }} in repository ${{ github.repository }}. - - PR TITLE: ${{ github.event.pull_request.title }} - - Please review this pull request and provide feedback on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security concerns - - Test coverage - - IMPORTANT NOTES: - - Review the other comments on the pull request - including any prior reviews. - - If you are reviewing changes beyond the first creation of the pull request, - make sure your comments are consistent with previous reviews. - - There's no need to repeat information unless it is critical and not - being reflected in comments or code. - - Be aware of prior reviews and that new file information may reflect - changes because of previous reviews. - - Use the repository's CLAUDE.md for guidance on style and conventions. - Be constructive and helpful in your feedback. - - IMPORTANT: Post exactly ONE comment using `gh pr comment`, then STOP. - Do not attempt additional actions after posting your review. diff --git a/.github/workflows/opencode.yml b/.github/workflows/opencode.yml index be5d030d..5a312012 100644 --- a/.github/workflows/opencode.yml +++ b/.github/workflows/opencode.yml @@ -21,10 +21,10 @@ jobs: issues: read steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Run opencode - uses: anomalyco/opencode/github@latest + uses: anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest env: ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }} with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 224d2811..61fb3ff5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,15 +24,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4 with: enable-cache: true @@ -61,7 +61,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Check for hardcoded localhost URLs in frontend run: | @@ -192,15 +192,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4 with: enable-cache: true @@ -236,7 +236,7 @@ jobs: echo "Note: -m v2 covers v2 code paths only; legacy v1 modules are excluded." - name: Upload coverage reports - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 with: file: ./coverage.xml flags: backend @@ -252,10 +252,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' @@ -282,7 +282,7 @@ jobs: fi - name: Upload coverage reports - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 with: directory: web-ui/coverage flags: frontend @@ -299,15 +299,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4 with: enable-cache: true @@ -388,7 +388,7 @@ jobs: - name: Upload E2E test reports if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: e2e-backend-reports path: | @@ -397,7 +397,7 @@ jobs: - name: Upload server logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: e2e-backend-server-logs path: /tmp/server.log @@ -741,10 +741,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: ${{ env.NODE_VERSION }} @@ -769,7 +769,7 @@ jobs: - name: Upload TestSprite results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: testsprite-results path: testsprite_tests/ From 754edacd5dbfa646a987078fb10bed48c5e88250 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 13 Jun 2026 16:40:55 -0700 Subject: [PATCH 2/2] chore(ci): align opencode.yml checkout to v4 SHA for pin consistency Addresses CodeRabbit: every other workflow pins actions/checkout to the v4 SHA; opencode.yml was on v6. No functional difference for a plain checkout. --- .github/workflows/opencode.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/opencode.yml b/.github/workflows/opencode.yml index 5a312012..b413a40f 100644 --- a/.github/workflows/opencode.yml +++ b/.github/workflows/opencode.yml @@ -21,7 +21,7 @@ jobs: issues: read steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Run opencode uses: anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest