diff --git a/.github/actions/basic-checks/action.yml b/.github/actions/basic-checks/action.yml new file mode 100644 index 0000000..d86d9ee --- /dev/null +++ b/.github/actions/basic-checks/action.yml @@ -0,0 +1,13 @@ +name: 'Basic CI Checks' +description: 'Runs basic CI checks (lint and typecheck) without secrets' + +runs: + using: 'composite' + steps: + - name: Run lint + run: task lint + shell: bash + + - name: Run typecheck + run: task typecheck + shell: bash diff --git a/.github/actions/full-checks/action.yml b/.github/actions/full-checks/action.yml new file mode 100644 index 0000000..9f9d7a0 --- /dev/null +++ b/.github/actions/full-checks/action.yml @@ -0,0 +1,55 @@ +name: 'Full CI Checks' +description: 'Runs full CI including integration tests with secrets' +inputs: + clerk-publishable-key: + description: 'Clerk publishable key' + required: true + clerk-secret-key: + description: 'Clerk secret key' + required: true + +runs: + using: 'composite' + steps: + - name: Check env vars set + run: | + if [ -z "${{ inputs.clerk-publishable-key }}" ]; then + echo "CLERK_PUBLISHABLE_KEY is not set" + exit 1 + fi + if [ -z "${{ inputs.clerk-secret-key }}" ]; then + echo "CLERK_SECRET_KEY is not set" + exit 1 + fi + shell: bash + + - name: Create .env + run: | + echo "CLERK_PUBLISHABLE_KEY=${{ inputs.clerk-publishable-key }}" >> .env + echo "CLERK_SECRET_KEY=${{ inputs.clerk-secret-key }}" >> .env + shell: bash + + - name: DEBUG - check python version + run: uv sync && uv run python --version + shell: bash + + - name: Run lint + run: task lint + shell: bash + + - name: Run typecheck + run: task typecheck + shell: bash + + - name: Initialize Reflex + run: uv run reflex init + working-directory: clerk_api_demo + shell: bash + + - name: Install playwright + run: uv run playwright install chromium + shell: bash + + - name: Run tests + run: task test + shell: bash diff --git a/.github/actions/setup-python-env/action.yml b/.github/actions/setup-python-env/action.yml new file mode 100644 index 0000000..b1d7856 --- /dev/null +++ b/.github/actions/setup-python-env/action.yml @@ -0,0 +1,28 @@ +name: 'Setup Python Environment' +description: 'Sets up Python, uv, and Task for CI' +inputs: + python-version: + description: 'Python version to setup' + required: true + github-token: + description: 'GitHub token for Task installation' + required: true + +runs: + using: 'composite' + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: "0.6.5" + + - name: Install Task + uses: arduino/setup-task@v2 + with: + version: 3.x + repo-token: ${{ inputs.github-token }} diff --git a/.github/workflows/_reusable-ci.yml b/.github/workflows/_reusable-ci.yml new file mode 100644 index 0000000..b64bc32 --- /dev/null +++ b/.github/workflows/_reusable-ci.yml @@ -0,0 +1,55 @@ +name: Reusable CI + +on: + workflow_call: + inputs: + checkout_ref: + description: 'Git ref to checkout' + required: false + type: string + default: '' + checkout_repository: + description: 'Repository to checkout (for forks)' + required: false + type: string + default: '' + check_type: + description: 'Type of checks to run: basic or full' + required: true + type: string + environment: + description: 'Environment to use for secrets (only for full checks)' + required: false + type: string + default: '' + +jobs: + ci: + runs-on: ubuntu-latest + strategy: + matrix: + python-versions: ["3.10", "3.11", "3.12", "3.13"] + environment: ${{ inputs.environment || null }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.checkout_ref || github.sha }} + repository: ${{ inputs.checkout_repository || github.repository }} + + - name: Setup Python Environment + uses: ./.github/actions/setup-python-env + with: + python-version: ${{ matrix.python-versions }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Basic Checks + if: inputs.check_type == 'basic' + uses: ./.github/actions/basic-checks + + - name: Run Full Checks + if: inputs.check_type == 'full' + uses: ./.github/actions/full-checks + with: + clerk-publishable-key: ${{ vars.CLERK_PUBLISHABLE_KEY }} + clerk-secret-key: ${{ secrets.CLERK_SECRET_KEY }} diff --git a/.github/workflows/ci-forks.yml b/.github/workflows/ci-forks.yml new file mode 100644 index 0000000..081fbe9 --- /dev/null +++ b/.github/workflows/ci-forks.yml @@ -0,0 +1,20 @@ +name: CI for Fork PRs + +on: + pull_request_target: + # Note: Repo must be set to require approval before running workflows from forks + # This only runs basic checks without secrets for safety + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + basic-checks: + uses: ./.github/workflows/_reusable-ci.yml + with: + checkout_ref: ${{ github.event.pull_request.head.sha }} + checkout_repository: ${{ github.event.pull_request.head.repo.full_name }} + check_type: 'basic' + secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b91a88..1ba3383 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,64 +13,9 @@ concurrency: cancel-in-progress: true jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - python-versions: ["3.10", "3.11", "3.12", "3.13"] - environment: - name: demo - - steps: - - uses: actions/checkout@v4 - - - name: Check env vars set - run: | - if [ -z "${{ vars.CLERK_PUBLISHABLE_KEY }}" ]; then - echo "CLERK_PUBLISHABLE_KEY is not set" - exit 1 - fi - if [ -z "${{ secrets.CLERK_SECRET_KEY }}" ]; then - echo "CLERK_SECRET_KEY is not set" - exit 1 - fi - - - name: Create .env - run: | - echo "CLERK_PUBLISHABLE_KEY=${{ vars.CLERK_PUBLISHABLE_KEY }}" >> .env - echo "CLERK_SECRET_KEY=${{ secrets.CLERK_SECRET_KEY }}" >> .env - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-versions }} - - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - version: "0.6.5" - - - name: DEBUG - check python version - run: uv sync && uv run python --version - - - name: Install Task - uses: arduino/setup-task@v2 - with: - version: 3.x - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Run lint - run: task lint - - - name: Run typecheck - run: task typecheck - - - name: Initialize Reflex - run: uv run reflex init - working-directory: clerk_api_demo - - - name: Install playwright - run: uv run playwright install chromium - - - name: Run tests - run: task test + ci: + uses: ./.github/workflows/_reusable-ci.yml + with: + check_type: 'full' + environment: 'demo' + secrets: inherit diff --git a/.github/workflows/full-ci-comment.yml b/.github/workflows/full-ci-comment.yml new file mode 100644 index 0000000..f6b9345 --- /dev/null +++ b/.github/workflows/full-ci-comment.yml @@ -0,0 +1,57 @@ +name: Full CI (Comment Triggered) + +on: + issue_comment: + types: [created] + +jobs: + trigger-check: + if: | + github.event.issue.pull_request && + contains(github.event.comment.body, '/run-full-ci') && + github.event.comment.author_association == 'OWNER' + runs-on: ubuntu-latest + outputs: + pr_head_sha: ${{ steps.pr.outputs.pr_head_sha }} + pr_head_repo: ${{ steps.pr.outputs.pr_head_repo }} + + steps: + - name: Get PR details + id: pr + uses: actions/github-script@v7 + with: + script: | + const pr = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + core.setOutput('pr_head_sha', pr.data.head.sha); + core.setOutput('pr_head_repo', pr.data.head.repo.full_name); + + full-ci: + needs: trigger-check + uses: ./.github/workflows/_reusable-ci.yml + with: + checkout_ref: ${{ needs.trigger-check.outputs.pr_head_sha }} + checkout_repository: ${{ needs.trigger-check.outputs.pr_head_repo }} + check_type: 'full' + environment: 'demo' + secrets: inherit + + comment-result: + needs: [trigger-check, full-ci] + if: always() + runs-on: ubuntu-latest + steps: + - name: Comment on PR + uses: actions/github-script@v7 + with: + script: | + const status = '${{ needs.full-ci.result }}' === 'success' ? '✅ PASSED' : '❌ FAILED'; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `Full CI ${status} for commit ${{ needs.trigger-check.outputs.pr_head_sha }}\n\nTriggered by: @${{ github.event.comment.user.login }}` + }); diff --git a/.github/workflows/full-ci-manual.yml b/.github/workflows/full-ci-manual.yml new file mode 100644 index 0000000..bab21f6 --- /dev/null +++ b/.github/workflows/full-ci-manual.yml @@ -0,0 +1,56 @@ +name: Full CI (Manual) + +on: + workflow_dispatch: + inputs: + pr_number: + description: 'PR number to run full CI against' + required: true + type: string + +jobs: + get-pr-info: + runs-on: ubuntu-latest + outputs: + head_sha: ${{ steps.pr-info.outputs.head_sha }} + head_repo: ${{ steps.pr-info.outputs.head_repo }} + steps: + - name: Get PR details + id: pr-info + uses: actions/github-script@v7 + with: + script: | + const pr = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: ${{ inputs.pr_number }} + }); + core.setOutput('head_sha', pr.data.head.sha); + core.setOutput('head_repo', pr.data.head.repo.full_name); + + full-ci: + needs: get-pr-info + uses: ./.github/workflows/_reusable-ci.yml + with: + checkout_ref: ${{ needs.get-pr-info.outputs.head_sha }} + checkout_repository: ${{ needs.get-pr-info.outputs.head_repo }} + check_type: 'full' + environment: 'demo' + secrets: inherit + + comment-result: + needs: [get-pr-info, full-ci] + if: always() + runs-on: ubuntu-latest + steps: + - name: Comment on PR + uses: actions/github-script@v7 + with: + script: | + const status = '${{ needs.full-ci.result }}' === 'success' ? '✅ PASSED' : '❌ FAILED'; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ inputs.pr_number }}, + body: `Full CI ${status} for commit ${{ needs.get-pr-info.outputs.head_sha }} (manually triggered)` + }); diff --git a/custom_components/reflex_clerk_api/clerk_provider.py b/custom_components/reflex_clerk_api/clerk_provider.py index 7de6e40..4bbba71 100644 --- a/custom_components/reflex_clerk_api/clerk_provider.py +++ b/custom_components/reflex_clerk_api/clerk_provider.py @@ -301,8 +301,8 @@ def add_imports( addl_imports: rx.ImportDict = { "@clerk/clerk-react": ["useAuth"], "react": ["useContext", "useEffect"], - "/utils/context": ["EventLoopContext"], - "/utils/state": ["Event"], + "$/utils/context": ["EventLoopContext"], + "$/utils/state": ["Event"], } return addl_imports