From 468c93d4090502ecaf713e040734f88322f42e01 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 7 Jul 2026 16:02:16 +0800 Subject: [PATCH] ci: harden release supply chain - Add CODEOWNERS so PRs to main require owner review (closes the gap where two collaborators could approve each other's changes). - Gate the release job behind a 'release' environment, so signing secrets are only unlocked after manual approval. - Stop ignoring the whole .github directory; this had been silently swallowing labeler.yml and workflows/labeler.yml, which are now tracked. Paired with a tag ruleset (created out-of-band) that restricts creation of v* tags to admins, this prevents a write collaborator from pushing a tag to trigger a signed release build. --- .github/CODEOWNERS | 14 +++++++ .github/labeler.yml | 74 +++++++++++++++++++++++++++++++++++ .github/workflows/labeler.yml | 17 ++++++++ .github/workflows/release.yml | 1 + .gitignore | 1 - 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/labeler.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..14198182c --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,14 @@ +# Code owners for cc-switch +# +# Branch protection on `main` has "Require review from Code Owners" enabled. +# With this file present, a PR cannot merge to `main` without an approval from +# the owner below. This closes the gap where two collaborators could approve +# each other's malicious PRs (a single non-owner approval is no longer enough). + +# Global fallback: every PR needs owner approval before merging to main. +* @farion1231 + +# Most sensitive paths — CI/signing/release and the Rust backend. Listed +# explicitly so they stay locked even if the global rule above is relaxed later. +/.github/ @farion1231 +/src-tauri/ @farion1231 diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..1e19b96b3 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,74 @@ +# Configuration for actions/labeler v5 +# Automatically labels PRs based on changed file paths + +frontend: + - changed-files: + - any-glob-to-any-file: + - "src/**" + - "index.html" + - "vite.config.ts" + - "vitest.config.ts" + - "tailwind.config.cjs" + - "postcss.config.cjs" + - "tsconfig.json" + - "tsconfig.node.json" + - "components.json" + - "tests/**" + +backend: + - changed-files: + - any-glob-to-any-file: + - "src-tauri/**" + +i18n: + - changed-files: + - any-glob-to-any-file: + - "src/locales/**" + +actions: + - changed-files: + - any-glob-to-any-file: + - ".github/**" + +dependencies: + - changed-files: + - any-glob-to-any-file: + - "package.json" + - "pnpm-lock.yaml" + - "pnpm-workspace.yaml" + - "src-tauri/Cargo.toml" + - "src-tauri/Cargo.lock" + +documentation: + - changed-files: + - any-glob-to-any-file: + - "*.md" + - "docs/**" + - "LICENSE" + +mcp: + - changed-files: + - any-glob-to-any-file: + - "src/components/mcp/**" + - "src/lib/api/mcp.ts" + - "src-tauri/src/mcp/**" + - "src-tauri/src/claude_mcp.rs" + - "src-tauri/src/gemini_mcp.rs" + - "src-tauri/src/commands/mcp.rs" + +skills: + - changed-files: + - any-glob-to-any-file: + - "src/components/skills/**" + - "src/lib/api/skills.ts" + - "src-tauri/src/commands/skill.rs" + - "src-tauri/src/services/skill.rs" + - "src-tauri/src/database/dao/skills.rs" + +proxy: + - changed-files: + - any-glob-to-any-file: + - "src/components/proxy/**" + - "src/lib/api/proxy.ts" + - "src-tauri/src/proxy/**" + - "src-tauri/src/commands/proxy.rs" diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..b8c91803c --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,17 @@ +name: Label PRs + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + sync-labels: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 703fc5f34..dde229900 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,7 @@ concurrency: jobs: release: runs-on: ${{ matrix.os }} + environment: release strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index 49f529856..525d4a7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,4 @@ flatpak-repo/ copilot-api .history CODEBUDDY.md -.github mainWindow.js