feat: add table copy/paste + preview before save π #3073
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| # Cancel in-progress runs on the same ref (branch or PR) to avoid redundant runs and save CI resources | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.sha || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| NODE_OPTIONS: "--max_old_space_size=4096" | |
| LOG_LEVEL: warn | |
| NX_CLOUD_DISTRIBUTED_EXECUTION: false | |
| AUTH_SFDC_CLIENT_ID: ${{ secrets.SFDC_CONSUMER_KEY }} | |
| AUTH_SFDC_CLIENT_SECRET: ${{ secrets.SFDC_CONSUMER_SECRET }} | |
| CONTENTFUL_HOST: cdn.contentful.com | |
| CONTENTFUL_SPACE: wuv9tl5d77ll | |
| CONTENTFUL_TOKEN: ${{ secrets.CONTENTFUL_TOKEN }} | |
| GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} | |
| GOOGLE_APP_ID: ${{ secrets.GOOGLE_APP_ID }} | |
| GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} | |
| GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} | |
| JETSTREAM_AUTH_OTP_SECRET: ${{ secrets.JETSTREAM_AUTH_OTP_SECRET }} | |
| JETSTREAM_AUTH_SECRET: ${{ secrets.JETSTREAM_AUTH_SECRET }} | |
| JETSTREAM_AUTH_SSO_SECRET: ${{ secrets.JETSTREAM_AUTH_SSO_SECRET }} | |
| JETSTREAM_CLIENT_URL: http://localhost:3333/app | |
| JETSTREAM_POSTGRES_DBURI: postgres://postgres:postgres@localhost:5432/postgres | |
| PRISMA_TEST_DB_URI: postgres://postgres:postgres@localhost:5432/postgres | |
| JETSTREAM_SAML_SP_ENTITY_ID_PREFIX: urn:jetstream:test | |
| JETSTREAM_SERVER_DOMAIN: localhost:3333 | |
| JETSTREAM_SERVER_URL: http://localhost:3333 | |
| JETSTREAM_SESSION_SECRET: ${{ secrets.JETSTREAM_SESSION_SECRET }} | |
| NX_PUBLIC_AMPLITUDE_KEY: ${{ secrets.NX_PUBLIC_AMPLITUDE_KEY }} | |
| NX_PUBLIC_CLIENT_URL: "http://localhost:3333/app" | |
| NX_PUBLIC_SENTRY_DSN: ${{ secrets.NX_PUBLIC_SENTRY_DSN }} | |
| NX_PUBLIC_SERVER_URL: "http://localhost:3333" | |
| DESKTOP_ORG_ENCRYPTION_SECRET: ${{ secrets.DESKTOP_ORG_ENCRYPTION_SECRET }} | |
| SFDC_API_VERSION: "67.0" | |
| SFDC_CALLBACK_URL: http://localhost:3333/oauth/sfdc/callback | |
| SFDC_CONSUMER_KEY: ${{ secrets.SFDC_CONSUMER_KEY }} | |
| SFDC_CONSUMER_SECRET: ${{ secrets.SFDC_CONSUMER_SECRET }} | |
| SFDC_ENCRYPTION_KEY: ${{ secrets.SFDC_ENCRYPTION_KEY }} | |
| JWT_ENCRYPTION_KEY: ${{ secrets.JWT_ENCRYPTION_KEY }} | |
| jobs: | |
| # Build application | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| services: | |
| # Used for integration tests (notably cron job tests) | |
| postgres: | |
| image: postgres:16.1-alpine | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| name: Checkout [master] | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup branch tracking | |
| if: success() && github.ref != 'refs/heads/main' | |
| run: git branch --track main origin/main | |
| - name: Derive appropriate SHAs for base and head for `nx affected` commands | |
| uses: nrwl/nx-set-shas@v5 | |
| - uses: pnpm/action-setup@v6 | |
| with: | |
| version: 11.8.0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| cache: "pnpm" | |
| - name: install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # Prisma client is no longer generated on install, so it must be generated explicitly | |
| - name: Generate database client | |
| run: pnpm db:generate | |
| - name: Run database migration | |
| run: pnpm db:migrate | |
| - name: Test all projects | |
| if: github.event_name == 'push' | |
| run: pnpm test:all | |
| - name: Test affected projects | |
| if: github.event_name == 'pull_request' | |
| run: pnpm test:affected | |
| - name: Build | |
| if: github.event_name == 'push' | |
| run: pnpm build:ci | |
| - name: Build affected | |
| if: github.event_name == 'pull_request' | |
| run: pnpm build:affected | |
| - name: Uploading artifacts | |
| if: github.event_name == 'push' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: dist-artifacts | |
| path: dist | |
| e2e: | |
| runs-on: ubuntu-latest | |
| env: | |
| E2E_LOGIN_PASSWORD: ${{ secrets.E2E_LOGIN_PASSWORD }} | |
| E2E_LOGIN_URL: "https://jetstream-e2e-dev-ed.develop.my.salesforce.com" | |
| E2E_LOGIN_USERNAME: "integration@jetstream.app.e2e" | |
| SFDC_CI_CONSUMER_KEY: ${{ secrets.SFDC_CI_CONSUMER_KEY }} | |
| SFDC_CI_PRIVATE_KEY_BASE64: ${{ secrets.SFDC_CI_PRIVATE_KEY_BASE64 }} | |
| EXAMPLE_USER_OVERRIDE: true | |
| EXAMPLE_USER_PASSWORD: "EXAMPLE_123!" | |
| services: | |
| postgres: | |
| image: postgres:16.1-alpine | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| name: Checkout [master] | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup branch tracking | |
| if: success() && github.ref != 'refs/heads/main' | |
| run: git branch --track main origin/main | |
| - name: Derive appropriate SHAs for base and head for `nx affected` commands | |
| uses: nrwl/nx-set-shas@v5 | |
| - uses: pnpm/action-setup@v6 | |
| with: | |
| version: 11.8.0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| cache: "pnpm" | |
| - name: install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # Gate the slow E2E work on "is api or jetstream actually affected by this change?" | |
| # For push-to-main we always run (full-regression safety net). The job itself still | |
| # completes (exit 0) when skipped so branch protection stays satisfied. | |
| - id: guard | |
| name: Check if api or jetstream is affected | |
| run: | | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| echo "::notice::Running E2E β push event always runs the full suite" | |
| exit 0 | |
| fi | |
| affected=$(pnpm nx show projects --affected --type=app) | |
| echo "Affected apps:" | |
| echo "$affected" | |
| if echo "$affected" | grep -qE '^(api|jetstream)$'; then | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| echo "::notice::Running E2E β api or jetstream is affected" | |
| else | |
| echo "should_run=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::Skipping E2E β neither api nor jetstream is affected" | |
| fi | |
| # Prisma client must be generated before building since the api build imports it | |
| - name: Generate database client | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm db:generate | |
| - name: Build | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm build:ci | |
| - name: Install Playwright dependencies | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm playwright install --with-deps | |
| - name: Run database migration | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm db:migrate | |
| - name: Seed DB | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm db:seed | |
| env: | |
| POSTGRES_HOST: localhost | |
| PGHOST: localhost | |
| PGPORT: 5432 | |
| PGUSER: postgres | |
| PGPASSWORD: postgres | |
| PGDATABASE: postgres | |
| - name: Run E2E tests | |
| if: steps.guard.outputs.should_run == 'true' | |
| run: pnpm playwright:test:with-server | |
| - name: Upload test results | |
| # Upload even on failure, but only when the suite actually ran. | |
| if: always() && steps.guard.outputs.should_run == 'true' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: playwright-report | |
| path: | | |
| apps/jetstream-e2e/playwright-report | |
| test-results |