diff --git a/.github/actions/init/action.yml b/.github/actions/init/action.yml new file mode 100644 index 00000000000..4bb0adf0d27 --- /dev/null +++ b/.github/actions/init/action.yml @@ -0,0 +1,117 @@ + +name: Setup Action +description: Checkout, setup node and dependencies +inputs: + node-version: + description: 'The node version to use' + required: false + default: '18' + playwright-enabled: + description: 'Enable Playwright?' + required: false + default: 'false' + turbo-enabled: + description: 'Enable Turbo?' + required: false + default: 'true' + turbo-cache-dir: + description: 'The cache dir to use for Turbo' + required: false + default: './.turbo-cache' + turbo-signature: + description: 'The signature to use for Turbo' + required: false + turbo-remote-only: + description: 'Only use remote cache?' + required: false + default: 'true' + turbo-team: + description: 'The team to use for Turbo remote auth' + required: true + turbo-token: + description: 'The token to use for Turbo remote auth' + required: true + +runs: + using: "composite" + steps: + - name: Configure Turborepo + id: turbo + uses: actions/github-script@v6 + env: + # envs are required to pass inputs to the script + ENABLED: ${{ inputs.turbo-enabled }} + CACHE_DIR: ${{ inputs.turbo-cache-dir }} + REMOTE_ONLY: ${{ inputs.turbo-remote-only }} + SIGNATURE: ${{ inputs.turbo-signature }} + TEAM: ${{ inputs.turbo-team }} + TOKEN: ${{ inputs.turbo-token }} + with: + script: | + const os = require('os') + const cpus = + typeof os.availableParallelism === "function" + ? os.availableParallelism() + : os.cpus().length; + + const { ENABLED, CACHE_DIR, SIGNATURE, REMOTE_ONLY, TEAM, TOKEN } = process.env + + core.exportVariable('TURBO_ARGS', + [ + '--output-logs=new-only', + `--cache-dir=${CACHE_DIR}`, + `--concurrency=${cpus}` + ].join(' ') + ) + + if (ENABLED === 'true') { + core.exportVariable('TURBO_TEAM', TEAM) + core.exportVariable('TURBO_TOKEN', TOKEN) + core.exportVariable('TURBO_REMOTE_ONLY', REMOTE_ONLY) + } + + if (SIGNATURE && SIGNATURE !== '') { + core.exportVariable('TURBO_REMOTE_CACHE_SIGNATURE_KEY', SIGNATURE) + } + + core.exportVariable('FORCE_COLOR', '1') + + - name: Turborepo CLI Args + shell: bash + run: echo $TURBO_ARGS + + - name: Setup NodeJS ${{ inputs.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ inputs.node-version }} + + - name: Cache node_modules + uses: actions/cache@v3 + id: npm-cache + with: + path: ./node_modules + key: ${{ runner.os }}-node-${{ inputs.node-version }}-node-modules-${{ hashFiles('**/package-lock.json') }} + + - name: Install NPM Dependencies + if: steps.npm-cache.outputs.cache-hit != 'true' + run: npm ci --audit=false --fund=false + shell: bash + + - name: Get Playwright Version + if: inputs.playwright-enabled == 'true' + shell: bash + id: playwright-version + run: echo "VERSION=$(node -e "console.log($(npm ls @playwright/test --json).dependencies['@playwright/test'].version)")" >> "$GITHUB_OUTPUT" + + - name: Cache Playwright Binaries + if: inputs.playwright-enabled == 'true' + uses: actions/cache@v3 + id: playwright-cache + with: + path: ~/.cache/ms-playwright + key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-playwright-${{ steps.playwright-version.outputs.VERSION }} + + - name: Install Playwright Browsers + if: inputs.playwright-enabled == 'true' && steps.playwright-cache.outputs.cache-hit != 'true' + shell: bash + run: npx playwright install --with-deps diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 81526e771ed..8a03be072a9 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -30,7 +30,7 @@ runs: name: Install dependencies shell: bash run: npm ci - - if: ${{ inputs.use-turbo-cache == 'true' }} + - if: ${{ inputs.use-turbo-cache == 'true' }} name: Download turbo cache uses: actions/download-artifact@v3 with: diff --git a/.github/actions/verdaccio/action.yml b/.github/actions/verdaccio/action.yml new file mode 100644 index 00000000000..197a55138d8 --- /dev/null +++ b/.github/actions/verdaccio/action.yml @@ -0,0 +1,40 @@ +name: Run Verdaccio +description: Checkout, setup node and dependencies +inputs: + auth-email: + description: 'The email to use for auth' + required: false + default: 'test@test.com' + auth-password: + description: 'The pass to use for auth' + required: false + default: 'pass' + auth-user: + description: 'The user to use for auth' + required: false + default: 'user' + publish-cmd: + description: 'The command to use to publish' + required: true + registry: + description: 'The registry to use' + required: false + default: 'http://localhost:4873' + +runs: + using: "composite" + steps: + - name: Update NPM Registry to Verdaccio + shell: bash + run: npm set registry ${{ inputs.registry }} + + - name: Run Verdaccio + shell: bash + run: | + nohup ./node_modules/.bin/verdaccio --config ./verdaccio.yaml & sleep 5 + ./node_modules/.bin/npm-cli-adduser -u ${{ inputs.auth-user }} -p ${{ inputs.auth-password }} -e ${{ inputs.auth-email }} -r ${{ inputs.registry }} + ./node_modules/.bin/npm-cli-login -u ${{ inputs.auth-user }} -p ${{ inputs.auth-password }} -e ${{ inputs.auth-email }} -r ${{ inputs.registry }} + + - name: Publish to Verdaccio + shell: bash + run: ${{ inputs.publish-cmd }} diff --git a/.github/workflows/base-changeset.yml b/.github/workflows/base-changeset.yml deleted file mode 100644 index 099307baa64..00000000000 --- a/.github/workflows/base-changeset.yml +++ /dev/null @@ -1,21 +0,0 @@ -on: - workflow_call: - -jobs: - check: - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - name: Checkout repo - uses: actions/checkout@v3 - with: - ref: ${{github.event.pull_request.head.sha}} - fetch-depth: 0 - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github.event.pull_request ) }} - run: | - echo "$GITHUB_CONTEXT" - - name: Setup - uses: ./.github/actions/setup - - run: | - if [ "${{ github.event.pull_request.user.login }}" = "clerk-cookie" ]; then echo 'Skipping' && exit 0; else npx changeset status --since=origin/main; fi diff --git a/.github/workflows/base-prettier.yml b/.github/workflows/base-prettier.yml deleted file mode 100644 index 46ca38c8d30..00000000000 --- a/.github/workflows/base-prettier.yml +++ /dev/null @@ -1,12 +0,0 @@ -on: - workflow_call: - -jobs: - check: - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - - run: npm run format:check diff --git a/.github/workflows/base-registry.yml b/.github/workflows/base-registry.yml deleted file mode 100644 index 964ccd8081f..00000000000 --- a/.github/workflows/base-registry.yml +++ /dev/null @@ -1,29 +0,0 @@ -on: - workflow_call: - -jobs: - registry: - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - - name: Configure npm to use Verdaccio - run: | - npm set registry http://localhost:4873/ - nohup ./node_modules/.bin/verdaccio --config ./verdaccio.publish.yaml & - sleep 5 - ./node_modules/.bin/npm-cli-adduser -u user -p pass -e test@test.com -r http://localhost:4873/ - ./node_modules/.bin/npm-cli-login -u user -p pass -e test@test.com -r http://localhost:4873/ - - name: Publish to Verdaccio - # The command below includes a sanity check - # and fails early if the default npm registry is used - run: | - npm run release:verdaccio - - name: List published packages - run: | - ls -all .verdaccio/storage/@clerk - - uses: actions/upload-artifact@v3 - with: - name: verdaccio - path: .verdaccio diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml deleted file mode 100644 index 13d9d020c55..00000000000 --- a/.github/workflows/checks.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: Quality checks and tests -on: - merge_group: - pull_request: - branches: [ main, main-v4 ] - -concurrency: - group: checks-${{ github.ref }} - cancel-in-progress: true - -jobs: - prettier: - name: Prettier - uses: ./.github/workflows/base-prettier.yml - - changeset: - name: Require changeset - uses: ./.github/workflows/base-changeset.yml - - build: - if: ${{ github.repository == 'clerkinc/javascript' }} - name: Build & publish - needs: [ prettier, changeset ] - uses: ./.github/workflows/base-build.yml - - eslint: - name: ESLint - needs: build - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - with: - use-turbo-cache: 'true' - - name: Run lint - run: npm run lint -- --output-logs=errors-only -- --quiet - - unit-tests: - name: Run unit tests - needs: build - runs-on: ${{ vars.RUNNER_LARGE }} - strategy: - matrix: - node-version: [ 18, 19 ] - steps: - - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - with: - use-turbo-cache: 'true' - - name: Run tests - run: npm run test:ci - - publint: - name: Run publint - needs: build - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - with: - use-turbo-cache: 'true' - - name: Lint packages using publint - run: npm run lint:publint - - attw: - name: Run attw - needs: build - runs-on: ${{ vars.RUNNER_LARGE }} - steps: - - uses: actions/checkout@v3 - - name: Setup - uses: ./.github/actions/setup - with: - use-turbo-cache: 'true' - - name: Lint types using attw - # Remove this when all related errors are fixed - continue-on-error: true - run: npm run lint:attw - - integration-generic: - name: Integration (Generic) - needs: build - uses: ./.github/workflows/base-e2e.yml - with: - SCRIPT: 'npm run test:integration:generic' - secrets: inherit - - integration-nextjs: - name: Integration (NextJS) - needs: build - uses: ./.github/workflows/base-e2e.yml - with: - SCRIPT: 'npm run test:integration:nextjs' - secrets: inherit - - integration-remix: - name: Integration (Remix) - needs: build - uses: ./.github/workflows/base-e2e.yml - with: - SCRIPT: 'npm run test:integration:remix' - secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1bc52b97a8..e46988188d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,20 +2,12 @@ name: CI on: workflow_dispatch: - merge_group: + # merge_group: pull_request: branches: - main - -env: - FORCE_COLOR: '1' - NODE_VERSION: '18' - TURBO_ARGS: --output-logs=new-only --cache-dir=./.turbo-cache --concurrency=8 - TURBO_TOKEN: ${{ secrets.TEST_TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TEST_TURBO_TEAM }} - TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - TURBO_REMOTE_ONLY: true - TURBO_CONCURRENCY: 8 # Available CPU in RUNNER_LARGE + - main-v4 + - ci-updates concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -25,8 +17,6 @@ jobs: formatting-linting: name: Formatting & Linting runs-on: ${{ vars.RUNNER_LARGE }} - env: - TURBO_REMOTE_ONLY: false steps: - name: Checkout Repo @@ -35,21 +25,23 @@ jobs: fetch-depth: 0 show-progress: false - - name: Setup NodeJS ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Cache node_modules - uses: actions/cache@v3 - id: npm-cache + - name: Setup + id: config + uses: ./.github/actions/init with: - path: ./node_modules - key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-node-modules-${{ hashFiles('**/package-lock.json') }} + turbo-remote-only: false + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - - name: Install NPM Dependencies - if: steps.npm-cache.outputs.cache-hit != 'true' - run: npm ci --audit=false --fund=false + - name: Test Envs + run: | + echo "TURBO_ARGS: $TURBO_ARGS" + echo "TURBO_TEAM: $TURBO_TEAM" + echo "TURBO_TOKEN: $TURBO_TOKEN" + echo "TURBO_REMOTE_ONLY: $TURBO_REMOTE_ONLY" + echo "TURBO_REMOTE_CACHE_SIGNATURE_KEY: $TURBO_REMOTE_CACHE_SIGNATURE_KEY" + echo "FORCE_COLOR: $FORCE_COLOR" - name: Require Changeset run: if [ "${{ github.event.pull_request.user.login }}" = "clerk-cookie" ]; then echo 'Skipping' && exit 0; else npx changeset status --since=origin/main; fi @@ -58,14 +50,14 @@ jobs: run: npm run format:check - name: Lint packages using publint - run: npm run lint:publint -- ${{ env.TURBO_ARGS }} + run: npm run lint:publint -- $TURBO_ARGS - name: Lint types using attw - run: npm run lint:attw -- ${{ env.TURBO_ARGS }} + run: npm run lint:attw -- $TURBO_ARGS continue-on-error: true # TODO: Remove this when all related errors are fixed - name: Run lint - run: npm run lint -- ${{ env.TURBO_ARGS }} -- --quiet + run: npm run lint -- $TURBO_ARGS -- --quiet unit-tests: name: Unit Tests @@ -83,24 +75,17 @@ jobs: fetch-depth: 0 show-progress: false - - name: Setup NodeJS ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - - name: Cache node_modules - uses: actions/cache@v3 - id: npm-cache + - name: Setup + id: config + uses: ./.github/actions/init with: - path: ./node_modules - key: ${{ runner.os }}-node-${{ matrix.node-version }}-node-modules-${{ hashFiles('**/package-lock.json') }} - - - name: Install NPM Dependencies - if: steps.npm-cache.outputs.cache-hit != 'true' - run: npm ci --audit=false --fund=false + node-version: ${{ matrix.node-version }} + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Run tests - run: npx turbo test ${{ env.TURBO_ARGS }} + run: npx turbo test $TURBO_ARGS env: NODE_VERSION: ${{ matrix.node-version }} @@ -120,65 +105,36 @@ jobs: fetch-depth: 0 show-progress: false - - name: Setup NodeJS ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 + - name: Setup + id: config + uses: ./.github/actions/init with: - node-version: ${{ env.NODE_VERSION }} - - - name: Cache node_modules - uses: actions/cache@v3 - id: npm-cache - with: - path: ./node_modules - key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-node-modules-${{ hashFiles('**/package-lock.json') }} - - - name: Install NPM Dependencies - if: steps.npm-cache.outputs.cache-hit != 'true' - run: npm ci --audit=false --fund=false + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} + playwright-enabled: true - - name: Get Playwright Version - id: playwright-version - run: echo "VERSION=$(node -e "console.log($(npm ls @playwright/test --json).dependencies['@playwright/test'].version)")" >> "$GITHUB_OUTPUT" - - - name: Cache Playwright Binaries - uses: actions/cache@v3 - id: playwright-cache + - name: Verdaccio + uses: ./.github/actions/verdaccio with: - path: ~/.cache/ms-playwright - key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-playwright-${{ steps.playwright-version.outputs.VERSION }} - - - name: Install Playwright Browsers - if: steps.playwright-cache.outputs.cache-hit != 'true' - run: npx playwright install --with-deps - - - name: Update NPM Registry - run: npm set registry http://localhost:4873/ - - - name: Run Verdaccio - run: | - nohup ./node_modules/.bin/verdaccio --config ./verdaccio.yaml & sleep 5 - ./node_modules/.bin/npm-cli-adduser -u user -p pass -e test@test.com -r http://localhost:4873/ - ./node_modules/.bin/npm-cli-login -u user -p pass -e test@test.com -r http://localhost:4873/ - - - name: Publish to Verdaccio - run: | - if [ "$(npm config get registry)" = "https://registry.npmjs.org/" ]; then echo 'Error: Using default registry' && exit 1; else npx turbo build ${{ env.TURBO_ARGS }} && npx changeset publish --no-git-tag; fi + publish-cmd: | + if [ "$(npm config get registry)" = "https://registry.npmjs.org/" ]; then echo 'Error: Using default registry' && exit 1; else npx turbo build $TURBO_ARGS && npx changeset publish --no-git-tag; fi - name: Install @clerk/backend in /integration working-directory: ./integration run: npm init -y && npm install @clerk/backend - - name: Run Playwright tests + - name: Run Integration Tests run: npm run test:integration:${{ matrix.test-name }} env: + E2E_CLERK_VERSION: 'latest' INTEGRATION_INSTANCE_KEYS: ${{ secrets.INTEGRATION_INSTANCE_KEYS }} MAILSAC_API_KEY: ${{ secrets.MAILSAC_API_KEY }} - E2E_CLERK_VERSION: 'latest' - - name: Upload Playwright Report for ${{ matrix.test-name }} - uses: actions/upload-artifact@v3 - if: always() - with: - name: playwright-report-${{ github.ref }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.test-name }} - path: playwright-report/ - retention-days: 1 + # - name: Upload Integration Report for ${{ matrix.test-name }} + # uses: actions/upload-artifact@v3 + # if: always() + # with: + # name: integration-report-${{ github.ref }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.test-name }} + # path: playwright-report/ + # retention-days: 1 diff --git a/package.json b/package.json index aabdcea86ee..c001b32c06a 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,8 @@ "release:canary": "TURBO_FORCE=true FORCE_COLOR=1 npm run build && changeset publish --tag canary --no-git-tag", "release:snapshot": "TURBO_FORCE=true FORCE_COLOR=1 npm run build && changeset publish --tag snapshot --no-git-tag", "release:staging": "TURBO_FORCE=true FORCE_COLOR=1 npm run build && changeset publish --tag staging --no-git-tag", - "release:verdaccio": "if [ \"$(npm config get registry)\" = \"https://registry.npmjs.org/\" ]; then echo 'Error: Using default registry' && exit 1; else TURBO_FORCE=true TURBO_CONCURRENCY=4 npm run build && changeset publish --no-git-tag; fi", "test": "FORCE_COLOR=1 turbo test --concurrency=${TURBO_CONCURRENCY:-80%}", "test:cache:clear": "FORCE_COLOR=1 turbo test:cache:clear --continue --concurrency=${TURBO_CONCURRENCY:-80%}", - "test:ci": "FORCE_COLOR=1 turbo test --concurrency=${TURBO_CONCURRENCY:-80%}", "test:integration:base": "DEBUG=1 npx playwright test --config integration/playwright.config.ts", "test:integration:deployment:nextjs": "DEBUG=1 npx playwright test --config integration/playwright.deployments.config.ts", "test:integration:generic": "E2E_APP_ID=react.vite.* npm run test:integration:base -- --grep @generic",