diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml deleted file mode 100644 index 2c3a718..0000000 --- a/.github/workflows/claude-code-review.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Claude Code Review - -on: - pull_request: - types: [opened, synchronize] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" - -jobs: - claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run Claude Code Review - id: claude-review - uses: anthropics/claude-code-action@beta - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - - # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4) - # model: "claude-opus-4-20250514" - - # Direct prompt for automated review (no @claude mention needed) - direct_prompt: | - Please review this pull request and provide feedback on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security concerns - - Test coverage - - Be constructive and helpful in your feedback. - - # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR - # use_sticky_comment: true - - # Optional: Customize review based on file types - # direct_prompt: | - # Review this PR focusing on: - # - For TypeScript files: Type safety and proper interface usage - # - For API endpoints: Security, input validation, and error handling - # - For React components: Performance, accessibility, and best practices - # - For tests: Coverage, edge cases, and test quality - - # Optional: Different prompts for different authors - # direct_prompt: | - # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' && - # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' || - # 'Please provide a thorough code review focusing on our coding standards and best practices.' }} - - # Optional: Add specific tools for running tests or linting - # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)" - - # Optional: Skip review for certain conditions - # if: | - # !contains(github.event.pull_request.title, '[skip-review]') && - # !contains(github.event.pull_request.title, '[WIP]') diff --git a/.github/workflows/claude-unified.yml b/.github/workflows/claude-unified.yml new file mode 100644 index 0000000..d444a31 --- /dev/null +++ b/.github/workflows/claude-unified.yml @@ -0,0 +1,71 @@ +name: Claude AI Integration + +on: + # Interactive Claude support + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + # Automatic PR review + pull_request: + types: [opened, synchronize] + +jobs: + claude-interactive: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Interactive + uses: anthropics/claude-code-action@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + additional_permissions: | + actions: read + + claude-review: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + uses: anthropics/claude-code-action@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + direct_prompt: | + Please review this pull request and provide feedback on: + - Code quality and TypeScript/Rust best practices + - Potential bugs or security issues + - Performance considerations for desktop app packaging + - CLI usability and error handling + - Test coverage completeness + + Be constructive and helpful in your feedback. + use_sticky_comment: true \ No newline at end of file diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml deleted file mode 100644 index fab4b58..0000000 --- a/.github/workflows/claude.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Claude Code - -on: - issue_comment: - types: [created] - pull_request_review_comment: - types: [created] - issues: - types: [opened, assigned] - pull_request_review: - types: [submitted] - -jobs: - claude: - if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - actions: read # Required for Claude to read CI results on PRs - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run Claude Code - id: claude - uses: anthropics/claude-code-action@beta - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - - # This is an optional setting that allows Claude to read CI results on PRs - additional_permissions: | - actions: read - - # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4) - # model: "claude-opus-4-20250514" - - # Optional: Customize the trigger phrase (default: @claude) - # trigger_phrase: "/claude" - - # Optional: Trigger when specific user is assigned to an issue - # assignee_trigger: "claude-bot" - - # Optional: Allow Claude to run specific commands - # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)" - - # Optional: Add custom instructions for Claude to customize its behavior for your project - # custom_instructions: | - # Follow our coding standards - # Ensure all new code has tests - # Use TypeScript for new files - - # Optional: Custom environment variables for Claude - # claude_env: | - # NODE_ENV: test diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml deleted file mode 100644 index 8babead..0000000 --- a/.github/workflows/code-quality.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Code Quality Check - -on: - push: - pull_request: - workflow_dispatch: - -permissions: - actions: write - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - formatting: - name: Code Formatting Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check EditorConfig compliance - uses: editorconfig-checker/action-editorconfig-checker@main - - - name: Run EditorConfig checker with exclusions - run: editorconfig-checker -exclude 'Cargo\.lock|dist/.*|.*\.(md|icns|ico|png|jpg|jpeg|gif|svg|desktop|wxs|plist|toml)$|cli\.js$|node_modules/.*|target/.*|src-tauri/(target|icons|png)/.*' - - - name: Check Prettier formatting - run: npx prettier --check . --ignore-unknown - - rust-quality: - name: Rust Code Quality - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - fail-fast: false - defaults: - run: - shell: bash - working-directory: src-tauri - steps: - - uses: actions/checkout@v4 - - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - components: rustfmt, clippy - - - uses: rui314/setup-mold@v1 - if: matrix.os == 'ubuntu-latest' - - - uses: taiki-e/install-action@v1 - with: - tool: cargo-hack - - - name: Install Ubuntu dependencies - if: matrix.os == 'ubuntu-latest' - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: libdbus-1-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev gnome-video-effects gnome-video-effects-extra - version: 1.0 - - - name: Check Rust formatting - run: cargo fmt --all -- --color=always --check - - - name: Run Clippy lints - run: cargo hack --feature-powerset --exclude-features cli-build --no-dev-deps clippy diff --git a/.github/workflows/contribute_list.yml b/.github/workflows/contribute_list.yml deleted file mode 100644 index ff55b14..0000000 --- a/.github/workflows/contribute_list.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Build Contribute List -on: - push: - branches: - - main - -jobs: - contrib-readme-job: - runs-on: ubuntu-latest - name: A job to automate contrib in readme - steps: - - name: Contribute List - uses: akhilmhdh/contributors-readme-action@v2.3.6 - with: - image_size: 90 - columns_per_row: 7 - env: - GITHUB_TOKEN: ${{ secrets.TOKEN }} diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index 23c8c2e..0000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build and Publish Docker Image - -on: - workflow_dispatch: # Manual - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -jobs: - build-and-push-image: - runs-on: ubuntu-22.04 - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v4 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=raw,value=latest,enable={{is_default_branch}} - type=sha - - - name: Build and push Docker image - uses: docker/build-push-action@v4 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - platforms: linux/amd64 diff --git a/.github/workflows/pake_build_next.yaml b/.github/workflows/pake_build_next.yaml deleted file mode 100644 index d8afcf7..0000000 --- a/.github/workflows/pake_build_next.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: Build All Popular Apps -on: - push: - tags: - - "V*" - -jobs: - read_apps_config: - name: Read Apps Config - runs-on: ubuntu-latest - outputs: - apps_name: ${{ steps.read-apps-config.outputs.apps_name }} - apps_config: ${{ steps.read-apps-config.outputs.apps_config }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Get Apps Config - id: read-apps-config - run: | - echo "apps_name=$(jq -c '[.[] | .name]' default_app_list.json)" >> $GITHUB_OUTPUT - echo "apps_config=$(jq -c '[.[]]' default_app_list.json)" >> $GITHUB_OUTPUT - - trigger_build: - needs: read_apps_config - name: ${{ matrix.title }} - strategy: - matrix: - name: ${{ fromJson(needs.read_apps_config.outputs.apps_name) }} - include: ${{ fromJSON(needs.read_apps_config.outputs.apps_config) }} - uses: ./.github/workflows/pake_build_single_app.yaml - with: - name: ${{ matrix.name }} - title: ${{ matrix.title }} - name_zh: ${{ matrix.name_zh }} - url: ${{ matrix.url }} diff --git a/.github/workflows/quality-and-test.yml b/.github/workflows/quality-and-test.yml new file mode 100644 index 0000000..74318c3 --- /dev/null +++ b/.github/workflows/quality-and-test.yml @@ -0,0 +1,177 @@ +name: Quality & Testing + +on: + push: + branches: [main, dev] + pull_request: + branches: [main, dev] + workflow_dispatch: + +permissions: + actions: write + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + formatting: + name: Code Formatting Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: latest + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check EditorConfig compliance + uses: editorconfig-checker/action-editorconfig-checker@main + + - name: Run EditorConfig checker with exclusions + run: editorconfig-checker -exclude 'Cargo\.lock|dist/.*|.*\.(md|icns|ico|png|jpg|jpeg|gif|svg|desktop|wxs|plist|toml)$|cli\.js$|node_modules/.*|target/.*|src-tauri/(target|icons|png)/.*' + + - name: Check Prettier formatting + run: npx prettier --check . --ignore-unknown + + rust-quality: + name: Rust Code Quality + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + fail-fast: false + defaults: + run: + shell: bash + working-directory: src-tauri + steps: + - uses: actions/checkout@v4 + + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt, clippy + + - uses: rui314/setup-mold@v1 + if: matrix.os == 'ubuntu-latest' + + - uses: taiki-e/install-action@v1 + with: + tool: cargo-hack + + - name: Install Ubuntu dependencies + if: matrix.os == 'ubuntu-latest' + uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + with: + packages: libdbus-1-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev gnome-video-effects gnome-video-effects-extra + version: 1.0 + + - name: Check Rust formatting + run: cargo fmt --all -- --color=always --check + + - name: Run Clippy lints + run: cargo hack --feature-powerset --exclude-features cli-build --no-dev-deps clippy + + cli-tests: + name: CLI Tests (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + fail-fast: false + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'npm' + + - name: Install Rust (Ubuntu) + if: matrix.os == 'ubuntu-latest' + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: x86_64-unknown-linux-gnu + + - name: Install Rust (Windows) + if: matrix.os == 'windows-latest' + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable-x86_64-msvc + target: x86_64-pc-windows-msvc + + - name: Install Rust (macOS) + if: matrix.os == 'macos-latest' + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: x86_64-apple-darwin + + - name: Install system dependencies (Ubuntu) + if: matrix.os == 'ubuntu-latest' + uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + with: + packages: libdbus-1-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev gnome-video-effects gnome-video-effects-extra + version: 1.1 + + - name: Install dependencies + run: npm install + + - name: Build CLI + run: npm run cli:build + + - name: Run CLI Test Suite + run: npm test + env: + CI: true + NODE_ENV: test + + - name: Test CLI Integration + shell: bash + run: | + echo "Testing CLI integration with weekly.tw93.fun..." + timeout 30s node dist/cli.js https://weekly.tw93.fun --name "CITestWeekly" --debug || true + echo "Integration test completed (expected to timeout)" + + summary: + name: Quality Summary + runs-on: ubuntu-latest + needs: [formatting, rust-quality, cli-tests] + if: always() + steps: + - name: Generate Summary + run: | + echo "# 🎯 Quality & Testing Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ "${{ needs.formatting.result }}" == "success" ]; then + echo "✅ **Code Formatting**: PASSED" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **Code Formatting**: FAILED" >> $GITHUB_STEP_SUMMARY + fi + + if [ "${{ needs.rust-quality.result }}" == "success" ]; then + echo "✅ **Rust Quality**: PASSED" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **Rust Quality**: FAILED" >> $GITHUB_STEP_SUMMARY + fi + + if [ "${{ needs.cli-tests.result }}" == "success" ]; then + echo "✅ **CLI Tests**: PASSED" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **CLI Tests**: FAILED" >> $GITHUB_STEP_SUMMARY + fi \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2812764 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,116 @@ +name: Release & Publish + +on: + push: + tags: + - "V*" + workflow_dispatch: + inputs: + release_apps: + description: "Build popular apps" + type: boolean + default: false + publish_docker: + description: "Publish Docker image" + type: boolean + default: false + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + # Update contributor list + update-contributors: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ secrets.TOKEN }} + + - name: Update Contributors + uses: akhilmhdh/contributors-readme-action@v2.3.6 + with: + image_size: 90 + columns_per_row: 7 + env: + GITHUB_TOKEN: ${{ secrets.TOKEN }} + + # Build and release popular apps + release-apps: + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || + (github.event_name == 'workflow_dispatch' && inputs.release_apps) + runs-on: ubuntu-latest + outputs: + apps_name: ${{ steps.read-apps-config.outputs.apps_name }} + apps_config: ${{ steps.read-apps-config.outputs.apps_config }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Get Apps Config + id: read-apps-config + run: | + echo "apps_name=$(jq -c '[.[] | .name]' default_app_list.json)" >> $GITHUB_OUTPUT + echo "apps_config=$(jq -c '[.[]]' default_app_list.json)" >> $GITHUB_OUTPUT + + build-popular-apps: + needs: release-apps + if: needs.release-apps.result == 'success' + strategy: + matrix: + name: ${{ fromJson(needs.release-apps.outputs.apps_name) }} + include: ${{ fromJSON(needs.release-apps.outputs.apps_config) }} + uses: ./.github/workflows/pake_build_single_app.yaml + with: + name: ${{ matrix.name }} + title: ${{ matrix.title }} + name_zh: ${{ matrix.name_zh }} + url: ${{ matrix.url }} + + # Publish Docker image + publish-docker: + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || + (github.event_name == 'workflow_dispatch' && inputs.publish_docker) + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=tag + type=sha + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64 \ No newline at end of file