diff --git a/.github/workflows/ci-internal-apps.yaml b/.github/workflows/ci-internal-apps.yaml index 6b5c41491e..e32dbb4573 100644 --- a/.github/workflows/ci-internal-apps.yaml +++ b/.github/workflows/ci-internal-apps.yaml @@ -6,6 +6,12 @@ on: - main pull_request: workflow_dispatch: + inputs: + application: + description: 'Internal app folder name to test (e.g. "twenty-linear"). Leave empty to test all non-excluded apps. Runs even if in CI_EXCLUDED_APPLICATIONS.' + required: false + default: '' + type: string permissions: contents: read @@ -50,6 +56,7 @@ jobs: env: EVENT_NAME: ${{ github.event_name }} CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + APPLICATION_INPUT: ${{ inputs.application }} run: | node <<'NODE' const fs = require('fs'); @@ -60,7 +67,6 @@ jobs: // app from this list once its checks pass, and delete the list entirely // once every application is covered. const CI_EXCLUDED_APPLICATIONS = ['call-recording', 'exa', 'people-data-labs', 'self-hosting', 'twenty-discord', 'twenty-fireflies', 'twenty-for-twenty', 'twenty-last-contact', 'twenty-linear', 'twenty-meeting-bot', 'twenty-partners', 'twenty-slack']; - const rootNodeVersion = fs.existsSync('.nvmrc') ? fs.readFileSync('.nvmrc', 'utf8').trim() : '24'; const eventName = process.env.EVENT_NAME; const changedFiles = JSON.parse(process.env.CHANGED_FILES || '[]'); const changedApps = new Set(); @@ -68,20 +74,23 @@ jobs: const match = file.match(/^packages\/twenty-apps\/internal\/([^/]+)\//); if (match) changedApps.add(match[1]); } + const requestedApp = (process.env.APPLICATION_INPUT || '').trim(); const matrix = fs.readdirSync(root, { withFileTypes: true }) .filter((entry) => entry.isDirectory() && entry.name !== 'node_modules') .map((entry) => entry.name) .filter((name) => fs.existsSync(path.join(root, name, 'package.json'))) - .filter((name) => !CI_EXCLUDED_APPLICATIONS.includes(name)) - .filter((name) => eventName === 'workflow_dispatch' || changedApps.has(name)) + .filter((name) => { + if (eventName === 'workflow_dispatch') { + return requestedApp ? name === requestedApp : !CI_EXCLUDED_APPLICATIONS.includes(name); + } + return !CI_EXCLUDED_APPLICATIONS.includes(name) && changedApps.has(name); + }) .map((name) => { const appPath = path.join(root, name); const scripts = JSON.parse(fs.readFileSync(path.join(appPath, 'package.json'), 'utf8')).scripts || {}; - const nvmrc = path.join(appPath, '.nvmrc'); return { name, path: appPath, - nodeVersion: fs.existsSync(nvmrc) ? fs.readFileSync(nvmrc, 'utf8').trim() : rootNodeVersion, hasTypecheck: Boolean(scripts.typecheck), hasUnit: Boolean(scripts['test:unit']), hasIntegration: Boolean(scripts.test), @@ -114,7 +123,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: ${{ matrix.app.nodeVersion }} + node-version-file: '.nvmrc' cache: yarn cache-dependency-path: ${{ matrix.app.path }}/yarn.lock diff --git a/packages/create-twenty-app/src/constants/template/README.md b/packages/create-twenty-app/src/constants/template/README.md index ca0f57eeae..4728d9ffa0 100644 --- a/packages/create-twenty-app/src/constants/template/README.md +++ b/packages/create-twenty-app/src/constants/template/README.md @@ -13,9 +13,6 @@ Run `yarn twenty help` to list all available commands. - `yarn twenty dev` - Start the development server and sync your app - `yarn twenty docker:status` - Check the local Twenty server status - `yarn twenty docker:start` - Start the local Twenty server -- `yarn lint` - Lint the codebase -- `yarn typecheck` - Type-check the codebase -- `yarn test:unit` - Run unit tests - `yarn test` - Run integration tests ## Learn More diff --git a/packages/create-twenty-app/src/constants/template/github/workflows/ci.yml b/packages/create-twenty-app/src/constants/template/github/workflows/ci.yml index 28104ffadc..9112ecb495 100644 --- a/packages/create-twenty-app/src/constants/template/github/workflows/ci.yml +++ b/packages/create-twenty-app/src/constants/template/github/workflows/ci.yml @@ -23,6 +23,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Spawn Twenty test instance + id: twenty + uses: twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main + with: + twenty-version: ${{ env.TWENTY_VERSION }} + - name: Enable Corepack run: corepack enable @@ -35,21 +41,6 @@ jobs: - name: Install dependencies run: yarn install --immutable - - name: Lint - run: yarn lint - - - name: Typecheck - run: yarn typecheck - - - name: Run unit tests - run: yarn test:unit - - - name: Spawn Twenty test instance - id: twenty - uses: twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main - with: - twenty-version: ${{ env.TWENTY_VERSION }} - - name: Run integration tests run: yarn test env: diff --git a/packages/create-twenty-app/src/constants/template/package.json b/packages/create-twenty-app/src/constants/template/package.json index 58dbc8b260..a41cd81902 100644 --- a/packages/create-twenty-app/src/constants/template/package.json +++ b/packages/create-twenty-app/src/constants/template/package.json @@ -13,9 +13,7 @@ "twenty": "twenty", "lint": "oxlint -c .oxlintrc.json .", "lint:fix": "oxlint --fix -c .oxlintrc.json .", - "typecheck": "tsc --noEmit -p tsconfig.spec.json", "test": "vitest run", - "test:unit": "vitest run --config vitest.unit.config.ts --passWithNoTests", "test:watch": "vitest" }, "dependencies": {}, diff --git a/packages/create-twenty-app/src/constants/template/vitest.unit.config.ts b/packages/create-twenty-app/src/constants/template/vitest.unit.config.ts deleted file mode 100644 index e0d140015b..0000000000 --- a/packages/create-twenty-app/src/constants/template/vitest.unit.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import tsconfigPaths from 'vite-tsconfig-paths'; -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - plugins: [ - tsconfigPaths({ - projects: ['tsconfig.spec.json'], - ignoreConfigErrors: true, - }), - ], - test: { - include: ['src/**/*.test.ts'], - }, -});