From d96797ae6a57feb4accbf68329fd40ee9ffa1880 Mon Sep 17 00:00:00 2001 From: dschom Date: Tue, 29 Aug 2023 11:19:54 -0700 Subject: [PATCH] task(CI): Improve nx caching for CI pipelines Because: - Not all CI operations where taking advantage of NX caches This Commit: - Adjusts nx.json config to ensure correct caching behavior - Adjusts nx.json config to ensure proper target chains. ie build is dependent on pre-build - Uses nx to directly run integration tests - Uses nx to directly run unit tests - Phases out dependency on generated .list files - Ensures 'start up' for services for functional tests is done with nx and uses nx caches. - Creates nx tags to facilitate test commands - Fixes linter errors encountered - Updates docker images to nx for builds - Updates nx ignore files --- .circleci/base-install.sh | 14 +- .circleci/build-ts-packages.sh | 32 -- .circleci/config.yml | 406 +++++++++--------- .circleci/create-lists.sh | 55 --- .circleci/report-coverage.sh | 18 - .circleci/run-list-parallel.sh | 105 ----- .circleci/test-package.sh | 2 +- .eslintignore | 1 + .gitignore | 4 +- .nxignore | 5 + .vscode/settings.json | 11 +- _dev/docker/ci/Dockerfile | 10 +- _dev/docker/ci/Dockerfile.dockerignore | 5 +- _dev/docker/mono/build.sh | 2 +- _dev/pm2/start.sh | 1 + _scripts/check-url.sh | 7 +- _scripts/pm2-all.sh | 26 +- apps/payments/next/project.json | 2 +- libs/payments/cart/project.json | 2 +- libs/payments/paypal/project.json | 2 +- libs/shared/db/mysql/account/project.json | 2 +- libs/shared/db/mysql/core/project.json | 2 +- libs/shared/error/project.json | 2 +- libs/shared/log/project.json | 2 +- libs/shared/metrics/statsd/project.json | 2 +- nx.json | 148 ++++++- package.json | 6 +- packages/123done/package.json | 5 + packages/browserid-verifier/package.json | 5 + packages/eslint-plugin-fxa/package.json | 10 +- packages/fortress/package.json | 5 + packages/functional-tests/package.json | 9 +- .../scripts/start-services.sh | 20 +- packages/fxa-admin-panel/package.json | 24 +- packages/fxa-admin-panel/scripts/test-ci.sh | 4 +- packages/fxa-admin-server/package.json | 14 +- packages/fxa-admin-server/pm2.config.js | 4 +- packages/fxa-auth-client/package.json | 13 +- packages/fxa-auth-server/package.json | 57 +-- packages/fxa-auth-server/pm2.config.js | 115 ++--- .../fxa-auth-server/scripts/start-local.sh | 9 - packages/fxa-auth-server/scripts/test-ci.sh | 17 +- packages/fxa-content-server/package.json | 31 +- packages/fxa-content-server/pm2.config.js | 94 ++-- .../scripts/start-services.sh | 34 +- packages/fxa-customs-server/package.json | 6 + packages/fxa-dev-launcher/package.json | 3 +- packages/fxa-event-broker/package.json | 7 +- packages/fxa-event-broker/scripts/test-ci.sh | 2 +- packages/fxa-geodb/README.md | 2 +- packages/fxa-geodb/package.json | 6 + packages/fxa-graphql-api/package.json | 14 +- packages/fxa-graphql-api/pm2.config.js | 4 +- .../src/backend/legal.service.spec.ts | 10 +- .../fxa-graphql-api/src/gql/gql.module.ts | 1 - packages/fxa-graphql-api/src/gql/lib/error.ts | 15 +- packages/fxa-payments-server/package.json | 39 +- packages/fxa-payments-server/pm2.config.js | 154 +++---- .../fxa-payments-server/scripts/test-ci.sh | 4 +- packages/fxa-profile-server/package.json | 17 +- .../fxa-profile-server/scripts/test-ci.sh | 2 +- packages/fxa-react/package.json | 32 +- packages/fxa-react/pm2.config.js | 12 +- packages/fxa-react/scripts/test-ci.sh | 3 +- packages/fxa-settings/.eslintignore | 1 + .../design-guide/pages/Breakpoints.tsx | 3 +- .../.storybook/design-guide/pages/Colors.tsx | 3 +- .../design-guide/pages/Introduction.tsx | 3 +- .../.storybook/design-guide/pages/Spacing.tsx | 5 +- .../design-guide/pages/Typography.tsx | 3 +- packages/fxa-settings/package.json | 44 +- packages/fxa-settings/pm2.config.js | 126 +++--- .../components/FormPassword/index.test.tsx | 2 +- .../components/GetDataTrio/index.stories.tsx | 6 +- .../components/LinkExpired/index.stories.tsx | 1 - .../LinkExpiredResetPassword/index.test.tsx | 1 - .../index.test.tsx | 4 - .../PasswordInfoBalloon/index.test.tsx | 2 +- .../index.stories.tsx | 2 +- .../src/components/Settings/Modal/index.tsx | 2 +- .../Settings/PageDeleteAccount/index.tsx | 7 +- .../integrations/oauth-integration.test.ts | 2 +- .../models/integrations/oauth-integration.ts | 2 - .../integrations/sync-basic-integration.ts | 1 - .../models/verification/verification-info.ts | 9 +- .../pages/CannotCreateAccount/index.test.tsx | 2 +- .../src/pages/Clear/index.test.tsx | 2 +- .../src/pages/Legal/index.test.tsx | 2 +- .../src/pages/ResetPassword/index.tsx | 8 +- packages/fxa-shared/package.json | 14 +- packages/fxa-shared/pm2.config.js | 30 +- 91 files changed, 981 insertions(+), 983 deletions(-) delete mode 100755 .circleci/build-ts-packages.sh delete mode 100755 .circleci/create-lists.sh delete mode 100755 .circleci/report-coverage.sh delete mode 100755 .circleci/run-list-parallel.sh create mode 100644 .nxignore delete mode 100755 packages/fxa-auth-server/scripts/start-local.sh create mode 100644 packages/fxa-settings/.eslintignore diff --git a/.circleci/base-install.sh b/.circleci/base-install.sh index 44beede1f4..1b459ecd47 100755 --- a/.circleci/base-install.sh +++ b/.circleci/base-install.sh @@ -45,19 +45,7 @@ else echo '==============================================================================' echo 'Congrats! No changes detected on yarn.lock.' echo '------------------------------------------------------------------------------' - echo 'Skipping yarn install and running postinstall directly.\n' + echo 'Skipping yarn install!\n' echo '==============================================================================' echo -e '\n\n' - - - # If we skip the yarn install, postinstall may still be needed on any workspace that have changed - # since the base docker image was built. We exclude wome workspaces because their post install is just - # another build call, which will be taken care of in a following step. - set -x - yarn workspaces foreach \ - --topological-dev \ - -piv $(cat .lists/postinstall-includes.list) \ - --exclude=fxa-shared \ - --exclude=fxa-auth-client \ - run postinstall fi diff --git a/.circleci/build-ts-packages.sh b/.circleci/build-ts-packages.sh deleted file mode 100755 index b647fb9e89..0000000000 --- a/.circleci/build-ts-packages.sh +++ /dev/null @@ -1,32 +0,0 @@ -#/bin/bash -ex - -# The build list should usuallytake care of this, but just to be safe, always build -# these common workspaces. Our fucntional tests, which always regardless of the change -# set now assume these workspaces have been pre-built. -yarn workspaces foreach \ - -piv \ - --topological-dev \ - --include fxa-shared \ - --include fxa-auth-client \ - --include fxa-react \ - run build - -# Build workspaces with changes. -LIST=".lists/ts-build-includes.list" -if [[ ! -f $LIST ]]; then - echo "List isn't a valid file: $LIST" - exit 1 -fi -if [[ ! -s .lists/$LIST ]]; then - echo "$LIST contains no operations. Exiting early!" - exit 0 -fi - -yarn workspaces foreach \ - -piv \ - --topological-dev \ - $(cat $LIST) \ - --exclude fxa-shared \ - --exclude fxa-auth-client \ - --exclude fxa-react \ - run compile diff --git a/.circleci/config.yml b/.circleci/config.yml index 0cdad62fb8..9740204cf4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,6 +54,8 @@ executors: resource_class: small docker: - image: cimg/node:18.17 + environment: + HUSKY_SKIP_INSTALL: 1 # For creating docker builds docker-build-executor: @@ -75,16 +77,18 @@ executors: YARN_ENABLE_GLOBAL_CACHE: true # Enabling hard links saves about 1.2 GB of space in the image. YARN_NM_MODE: hardlinks-global + HUSKY_SKIP_INSTALL: 1 # Contains prebuilt image with low install overhead. Perfect for the first build # step, and the saving the initial a workspace state. build-executor: docker: - - image: mozilla/fxa-circleci:ci-builder + - image: mozilla/fxa-circleci:ci-builder-nx environment: NODE_ENV: development FIRESTORE_EMULATOR_HOST: localhost:9090 CUSTOMS_SERVER_URL: none + HUSKY_SKIP_INSTALL: 1 # Contains minimal image for running common jobs like linting or unit tests. # This image requires a restored workspace state. @@ -95,11 +99,12 @@ executors: default: medium resource_class: << parameters.resource_class >> docker: - - image: mozilla/fxa-circleci:ci-test-runner + - image: mozilla/fxa-circleci:ci-test-runner-nx environment: NODE_ENV: development FIRESTORE_EMULATOR_HOST: localhost:9090 CUSTOMS_SERVER_URL: none + HUSKY_SKIP_INSTALL: 1 # A minimal image for anything job needs infrastructure. Perfect for integration tests. # This image requires a restored workspace state. @@ -110,7 +115,7 @@ executors: default: large resource_class: << parameters.resource_class >> docker: - - image: mozilla/fxa-circleci:ci-test-runner + - image: mozilla/fxa-circleci:ci-test-runner-nx - image: cimg/mysql:8.0.28 command: --default-authentication-plugin=mysql_native_password - image: jdlk7/firestore-emulator @@ -122,6 +127,7 @@ executors: FIRESTORE_EMULATOR_HOST: localhost:9090 CUSTOMS_SERVER_URL: none REDIS_PASSWORD: fxa123 + HUSKY_SKIP_INSTALL: 1 # For anything that needs a full stack to run and needs browsers available for # ui test automation. This image requires a restored workspace state. @@ -132,7 +138,7 @@ executors: default: large resource_class: << parameters.resource_class >> docker: - - image: mozilla/fxa-circleci:ci-functional-test-runner + - image: mozilla/fxa-circleci:ci-functional-test-runner-nx - image: redis command: --requirepass fxa123 - image: memcached @@ -161,6 +167,7 @@ executors: REACT_CONVERSION_POST_VERIFY_CAD_VIA_QR_ROUTES: true CUSTOMS_SERVER_URL: none REDIS_PASSWORD: fxa123 + HUSKY_SKIP_INSTALL: 1 # Contains a pre-installed fxa stack and browsers for doing ui test # automation. Perfect for running smoke tests against remote targets. @@ -171,10 +178,11 @@ executors: default: medium+ resource_class: << parameters.resource_class >> docker: - - image: mozilla/fxa-circleci:ci-functional-test-runner + - image: mozilla/fxa-circleci:ci-functional-test-runner-nx environment: NODE_ENV: development CUSTOMS_SERVER_URL: none + HUSKY_SKIP_INSTALL: 1 commands: git-clone: @@ -236,13 +244,9 @@ commands: command: | ./_scripts/l10n/clone.sh ./.circleci/base-install.sh - ./.circleci/create-lists.sh ./_scripts/create-version-json.sh - yarn gql:allowlist - store_artifacts: path: ./packages/version.json - - store_artifacts: - path: ./.lists - store_artifacts: path: ./configs/gql @@ -299,23 +303,22 @@ commands: steps: - run: name: Linting - command: npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=3 -t lint + command: npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=2 -t lint compile: steps: + - run: + name: Pre building shared libraries + command: NODE_OPTIONS="--max-old-space-size=7168" npx nx run-many -t build --projects=tag:scope:shared:lib --parallel=2 + environment: + NODE_ENV: test + CI: false - run: name: Compiling TypeScript command: NODE_OPTIONS="--max-old-space-size=7168" npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=1 -t compile - - report-coverage: - # Not currently used. But should be soon once coverage reports are fixed up. - parameters: - list: - type: string - default: '' - steps: - - run: - command: ./.circleci/report-coverage.sh << parameters.list >> + environment: + NODE_ENV: test + CI: false run-playwright-tests: parameters: @@ -331,8 +334,9 @@ commands: else export FEATURE_FLAGS_SHOW_RECOVERY_KEY_V2=true fi - cd packages/functional-tests - TEST_FILES=$(circleci tests glob "tests/**/*.spec.ts") + cd packages/functional-tests/tests + TEST_FILES=$(circleci tests glob "./**/*.spec.ts") + cd .. echo $TEST_FILES | circleci tests run --command="xargs yarn playwright test --project=<< parameters.project >>" --verbose --split-by=timings environment: NODE_OPTIONS: --dns-result-order=ipv4first @@ -358,66 +362,55 @@ commands: - store_test_results: path: artifacts/tests - ts-build: + build: steps: - run: - name: Build Common Typescript Packages - command: NODE_OPTIONS="--max-old-space-size=7168" npx nx run-many --parallel=1 -t build --projects=fxa-shared,fxa-auth-client,fxa-react - - run: - name: Compile Changed Typescript Packages - command: NODE_OPTIONS="--max-old-space-size=7168" npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=3 -t compile + name: Build + command: NODE_OPTIONS="--max-old-space-size=7168" npx nx run-many -t build --parallel=2 --all --verbose + environment: + NODE_ENV: test + CI: false - save-workspace: + save-init-workspace: steps: - persist_to_workspace: root: /home/circleci/project paths: - - .lists - external - - configs/gql/allowlist - node_modules - - packages + - packages/**/node_modules + - packages/version.json + + save-build-workspace: + steps: + - persist_to_workspace: + name: Save Build Workspace + root: /home/circleci/project + paths: + - node_modules/.cache/nx + - packages/**/dist + - packages/**/public + - packages/**/src/styles + - packages/**/styles + - packages/**/vendor + - packages/**/var + - configs/gql/allowlist restore-workspace: steps: - attach_workspace: at: /home/circleci/project - run-tests: - parameters: - test_name: - type: string - # Name of file in ./lists folder holding tests to execute in parallel - list: - type: string - # Controls the number of parallel operations and essentially correlates to the --jobs argument of the - # parallel command. A value of NONE, indicates the argument is not supplied at all. - # For exact usage see: - # https://www.gnu.org/software/parallel/parallel_tutorial.html#number-of-simultaneous-jobs - max_jobs: - type: string - default: 'NONE' - index: - type: integer - default: 0 - total: - type: integer - default: 1 - steps: - - run: - name: << parameters.test_name >> - command: ./.circleci/run-list-parallel.sh << parameters.list >> << parameters.max_jobs >> << parameters.index >>:<< parameters.total >> - - store-artifacts - fail-fast: steps: - run: sleep 10 - run: name: Fail Fast when: on_fail - command: | - echo "Canceling workflow as a step resulted in failure" - node .circleci/cancel-jobs.mjs; + command: echo "DISABLE" + # command: | + # echo "Canceling workflow as a step resulted in failure" + # node .circleci/cancel-jobs.mjs; rebuild-check: parameters: @@ -459,7 +452,7 @@ commands: docker build . \ -f ./project/_dev/docker/ci/Dockerfile \ --target << parameters.target >> \ - -t mozilla/fxa-circleci:ci-<< parameters.target >> + -t mozilla/fxa-circleci:ci-<< parameters.target >>-nx create-fxa-ci-images: # Build CI images. Images are built on top of each other. Each is optimized for a specific task. @@ -488,10 +481,10 @@ commands: name: Push CI Images and Extract Yarn Cache command: | docker login -u $DOCKER_USER_fxa_circleci -p $DOCKER_PASS_fxa_circleci - .circleci/docker-copy-cache.sh mozilla/fxa-circleci:ci-builder - docker push mozilla/fxa-circleci:ci-test-runner - docker push mozilla/fxa-circleci:ci-functional-test-runner - docker push mozilla/fxa-circleci:ci-builder + .circleci/docker-copy-cache.sh mozilla/fxa-circleci:ci-builder-nx + docker push mozilla/fxa-circleci:ci-test-runner-nx + docker push mozilla/fxa-circleci:ci-functional-test-runner-nx + docker push mozilla/fxa-circleci:ci-builder-nx wait jobs: @@ -528,7 +521,6 @@ jobs: type: executor force-deploy: type: boolean - default: false executor: << parameters.executor >> steps: # Run with layer caching to speed up builds @@ -536,7 +528,7 @@ jobs: docker_layer_caching: true - git-clone - rebuild-check: - force-deploy: << pipeline.parameters.force-deploy-fxa-ci-images >> + force-deploy: << parameters.force-deploy >> - install-test-browsers - cache-restore-yarn - create-fxa-ci-images @@ -545,19 +537,27 @@ jobs: # The initial step for many pipelines, this step installs packages and does a build on # the code. It then stores the resulting state into a CircleCI workspace for later # use. - build: + init: executor: build-executor resource_class: large steps: - git-checkout - provision - - ts-build - - save-workspace + - save-init-workspace + + build: + executor: default-executor + resource_class: large + steps: + - git-checkout + - restore-workspace + - build + - save-build-workspace # Runs linter on packages that have changes. lint: executor: default-executor - resource_class: medium + resource_class: small steps: - git-checkout - restore-workspace @@ -574,51 +574,54 @@ jobs: # Runs unit tests in parallel across packages with changes. unit-test: executor: default-executor - resource_class: large - steps: - - git-checkout - - restore-workspace - - run: - name: Run unit tests - command: npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=1 -t test-unit - environment: - NODE_ENV: test - - integration-test-libs: - executor: fullstack-executor resource_class: medium+ steps: - git-checkout - restore-workspace - - wait-for-infrastructure + - run: + name: Build shared libs + command: NODE_OPTIONS="--max-old-space-size=7168" npx nx run-many -t build --projects=tag:scope:shared:lib --parallel=2 - run: name: Run unit tests - command: npx nx run-many -t test-integration --projects=tag:lib + command: npx nx affected --base=main --head=$CIRCLE_SHA1 --parallel=2 -t test-unit environment: NODE_ENV: test + CI: false + - store-artifacts # Runs integration tests suites across packages with changes. Integration tests can take # longer to run, so this job supports splitting. - integration-test-part: + integration-test: parameters: + target: + type: string + default: -t test-integration + projects: + type: string + default: --all + parallel: + type: string + default: --parallel=1 + nx_run: + type: string + default: run-many resource_class: type: string default: medium - index: - type: integer - total: - type: integer executor: fullstack-executor + resource_class: << parameters.resource_class >> steps: - git-checkout - restore-workspace - wait-for-infrastructure - - run-tests: - test_name: Integration Test (many) - list: integration-test.list - max_jobs: '1' - index: << parameters.index >> - total: << parameters.total >> + - run: + name: Run API Integration Tests + command: | + npx nx << parameters.nx_run >> << parameters.parallel >> << parameters.target >> << parameters.projects >> + environment: + NODE_ENV: test + CI: false + - store-artifacts # This job is manually triggered for now. see .circleci/README.md test-content-server-remote: @@ -684,7 +687,7 @@ jobs: default: large parallelism: type: integer - default: 4 + default: 6 executor: functional-test-executor resource_class: << parameters.resource_class >> parallelism: << parameters.parallelism >> @@ -700,6 +703,8 @@ jobs: - run: name: Start services for playwright tests command: ./packages/functional-tests/scripts/start-services.sh + environment: + NODE_ENV: test - run-playwright-tests: project: local - store-artifacts @@ -715,6 +720,16 @@ jobs: command: | STORYBOOKS_USE_YARN_WORKSPACES=false npx github:mozilla-fxa/storybook-gcp-publisher + update-yarn-cache: + executor: default-executor + resource_class: medium+ + steps: + - git-checkout + - run: + name: Base Install + command: ./.circleci/base-install.sh + - cache-save-yarn + # A nice way to finalize a workflow. This will also notify jira. on-complete: parameters: @@ -736,75 +751,58 @@ workflows: # run on PR drafts. when: << pipeline.parameters.enable_test_pull_request >> jobs: - - build: - name: Build (PR) + - init: + name: Init (PR) filters: branches: ignore: /main/ tags: ignore: /.*/ + - build: + name: Build (PR) + requires: + - Init (PR) - lint: name: Lint (PR) requires: - - Build (PR) + - Init (PR) + post-steps: + - fail-fast - compile: name: Compile (PR) requires: - - Build (PR) + - Init (PR) + post-steps: + - fail-fast - unit-test: name: Unit Test (PR) requires: - Build (PR) post-steps: - fail-fast - - integration-test-part: - name: Integration Test 1 (PR) - index: 0 - total: 6 + - integration-test: + name: Integration Test - Frontends (PR) + resource_class: large + nx_run: affected --base=main --head=$CIRCLE_SHA1 + projects: --exclude '*,!tag:scope:frontend' requires: - Build (PR) - - integration-test-part: - name: Integration Test 2 (PR) - index: 1 - total: 6 + - integration-test: + name: Integration Test - Servers (PR) + nx_run: affected --base=main --head=$CIRCLE_SHA1 + projects: --exclude '*,!tag:scope:server' requires: - Build (PR) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 3 (PR) - index: 2 - total: 6 + - integration-test: + name: Integration Test - Servers - Auth (PR) + nx_run: affected --base=main --head=$CIRCLE_SHA1 + projects: --exclude '*,!tag:scope:server:auth' requires: - Build (PR) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 4 (PR) - index: 3 - total: 6 - requires: - - Build (PR) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 5 (PR) - index: 4 - total: 6 - requires: - - Build (PR) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 6 (PR) - index: 5 - total: 6 - requires: - - Build (PR) - post-steps: - - fail-fast - - integration-test-libs: - name: Integration Test Libs (PR) + - integration-test: + name: Integration Test - Libraries (PR) + nx_run: affected --base=main --head=$CIRCLE_SHA1 + projects: --exclude '*,!tag:scope:shared:*' requires: - Build (PR) - playwright-functional-tests: @@ -824,10 +822,10 @@ workflows: - Lint (PR) - Compile (PR) - Unit Test (PR) - - Integration Test 1 (PR) - - Integration Test 2 (PR) - - Integration Test 3 (PR) - - Integration Test Libs (PR) + - Integration Test - Frontends (PR) + - Integration Test - Servers (PR) + - Integration Test - Servers - Auth (PR) + - Integration Test - Libraries (PR) - Functional Tests - Playwright (PR) - Deploy Storybooks (PR) @@ -901,6 +899,7 @@ workflows: - main tags: ignore: /.*/ + force-deploy: << pipeline.parameters.force-deploy-fxa-ci-images >> deploy_story_book: # This workflow is triggered after a PR lands on main. It requires approval. @@ -925,6 +924,13 @@ workflows: # live infrastructure. when: << pipeline.parameters.enable_test_and_deploy_tag >> jobs: + - init: + name: Init + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ - build: name: Build filters: @@ -932,6 +938,8 @@ workflows: ignore: /.*/ tags: only: /.*/ + requires: + - Init - lint: name: Lint filters: @@ -940,7 +948,7 @@ workflows: tags: only: /.*/ requires: - - Build + - Init - compile: name: Compile filters: @@ -949,7 +957,7 @@ workflows: tags: only: /.*/ requires: - - Build + - Init - unit-test: name: Unit Test filters: @@ -959,41 +967,45 @@ workflows: only: /.*/ requires: - Build - - integration-test-part: - name: Integration Test 1 + - integration-test: + name: Integration Test - Frontends + resource_class: large + projects: --tag=scope:frontend filters: branches: ignore: /.*/ tags: only: /.*/ - index: 0 - total: 3 requires: - Build - - integration-test-part: - name: Integration Test 2 + - integration-test: + name: Integration Test - Servers + projects: --tag=scope:server filters: branches: ignore: /.*/ tags: only: /.*/ - index: 1 - total: 3 requires: - Build - - integration-test-part: - name: Integration Test 3 + - integration-test: + name: Integration Test - Servers - Auth + projects: --tag=scope:server:auth filters: branches: ignore: /.*/ tags: only: /.*/ - index: 2 - total: 3 requires: - Build - - integration-test-libs: - name: Integration Test Libs + - integration-test: + name: Integration Test - Libraries + projects: --tag=scope:shared* + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ requires: - Build - playwright-functional-tests: @@ -1026,10 +1038,10 @@ workflows: - Lint - Compile - Unit Test - - Integration Test 1 - - Integration Test 2 - - Integration Test 3 - - Integration Test Libs + - Integration Test - Frontends + - Integration Test - Servers + - Integration Test - Servers - Auth + - Integration Test - Libraries - Functional Tests - Playwright - Create FxA Image @@ -1043,6 +1055,13 @@ workflows: branches: only: main jobs: + - init: + name: Init (nightly) + filters: + branches: + only: main + tags: + ignore: /.*/ - build: name: Build (nightly) filters: @@ -1050,46 +1069,41 @@ workflows: only: main tags: ignore: /.*/ + requires: + - Init (nightly) - lint: name: Lint (nightly) requires: - - Build (nightly) + - Init (nightly) - compile: name: Compile (nightly) requires: - - Build (nightly) + - Init (nightly) - unit-test: name: Unit Test (nightly) requires: - Build (nightly) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 1 (nightly) - index: 0 - total: 3 + - integration-test: + name: Integration Test - Frontends (nightly) + resource_class: large + projects: --tag=scope:frontend requires: - Build (nightly) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 2 (nightly) - index: 1 - total: 3 + - integration-test: + name: Integration Test - Servers (nightly) + projects: --tag=scope:server requires: - Build (nightly) - post-steps: - - fail-fast - - integration-test-part: - name: Integration Test 3 (nightly) - index: 2 - total: 3 + - integration-test: + name: Integration Test - Servers - Auth (nightly) + projects: --tag=scope:server:auth + target: --targets test-integration-local test-integration-remote test-integration-scripts requires: - Build (nightly) - post-steps: - - fail-fast - - integration-test-libs: - name: Integration Test Libs (nightly) + - integration-test: + name: Integration Test - Libraries (nightly) + # TODO - Get payments cart tests working + projects: --tag=scope:shared* --exclude=payments-cart requires: - Build (nightly) - playwright-functional-tests: @@ -1105,10 +1119,10 @@ workflows: - Lint (nightly) - Compile (nightly) - Unit Test (nightly) - - Integration Test 1 (nightly) - - Integration Test 2 (nightly) - - Integration Test 3 (nightly) - - Integration Test Libs (nightly) + - Integration Test - Frontends (nightly) + - Integration Test - Servers (nightly) + - Integration Test - Servers - Auth (nightly) + - Integration Test - Libraries (nightly) - Functional Tests - Playwright (nightly) - build-and-deploy-storybooks: name: Deploy Storybooks (nightly) diff --git a/.circleci/create-lists.sh b/.circleci/create-lists.sh deleted file mode 100755 index 4841ed9fd1..0000000000 --- a/.circleci/create-lists.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -e - -# Determine which workspaces have been modified -node .circleci/modules-to-test.js | tee packages/test.list - -# Create empty files -mkdir -p .lists -touch .lists/ts-build-includes.list -touch .lists/lint.list -touch .lists/lint-includes.list -touch .lists/unit-test.list -touch .lists/unit-test-includes.list -touch .lists/integration-test.list -touch .lists/integration-test-includes.list - -function genWorkspaceCmd() { - if [ -f "packages/$1/package.json" ]; then - if [[ $(cat packages/$1/package.json | jq ".scripts.\"$2\"") != null ]]; then - echo ".circleci/notify.sh 'Starting $1 -> $2' && NODE_ENV=test yarn workspace $1 run $2" >> .lists/$3 - fi - fi -} -function genIncludeArgs() { - if [ -f "packages/$1/package.json" ]; then - echo "Processing packages/$1/package.json " - if [[ $(cat packages/$1/package.json | jq ".scripts.\"$2\"") != null ]]; then - echo "--include $1" >> .lists/$3 - fi - fi -} - -if [[ $(cat packages/test.list) == *all* ]]; then - echo "Testing All Packages"; - ls -1 packages > .lists/test.list -else - cp packages/test.list .lists/test.list -fi - -# Loop over test.list and look for common scripts that might be applicable to run. -while read pkg -do - - # Creates a list of --include filters for yarn various workspace commands. - genIncludeArgs $pkg compile ts-build-includes.list - genIncludeArgs $pkg lint lint-includes.list - genIncludeArgs $pkg postinstall postinstall-includes.list - genIncludeArgs $pkg test-unit unit-test-includes.list - genIncludeArgs $pkg test-integration integration-test-includes.list - - # Creates a list of yarn workspace commands that can be run with gnu parallels. - # This will ensure the script exists prior to generating the command. - genWorkspaceCmd $pkg test-unit unit-test.list - genWorkspaceCmd $pkg test-integration integration-test.list - -done < .lists/test.list diff --git a/.circleci/report-coverage.sh b/.circleci/report-coverage.sh deleted file mode 100755 index 70636436b7..0000000000 --- a/.circleci/report-coverage.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -e - -LIST=$1 - -if [[ $LIST == "" ]]; then - echo "Missing list argument! Supply an argument. e.g. report-coverage.sh packages/unit-test-includes.list" - exit 1 -fi - -if [ ! -f $LIST ]; then - echo "List isn't a valid file: $LIST" - exit 1 -fi - -yarn workspaces foreach \ - -piv - $(cat $LIST) \ - exec '../../_scripts/report-coverage.sh $npm_package_name' diff --git a/.circleci/run-list-parallel.sh b/.circleci/run-list-parallel.sh deleted file mode 100755 index ddaf0cc6a7..0000000000 --- a/.circleci/run-list-parallel.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -e - -LIST=$1 -MAX_JOBS=$2 - -if [[ $1 == "" || $2 == "" ]]; then - echo "Missing arguments! Invocation should be, run-list-parallel.sh \$LIST \$MAX_JOBS \$GROUP. i.e. run-list-parallel.sh unit-test.list -1 3/4" - exit 1 -fi - -if [[ ! -f .lists/$LIST ]]; then - echo "List isn't a valid file: $LIST" - exit 1 -fi - -if [[ ! -s .lists/$LIST ]]; then - echo "$LIST contains no operations. Exiting early!" - exit 0 -fi - -JOBLOG="--joblog artifacts/tests/$LIST.log" - -if [[ $MAX_JOBS == "NONE" ]]; then - MAX_JOBS="" -else - MAX_JOBS="-j $2" -fi - -GROUP=$3 -if [[ $GROUP == "" ]]; then - INDEX=0 - TOTAL=1 -else - arr=(${GROUP//:/ }) - INDEX=$((${arr[0]})) - TOTAL=$((${arr[1]})) -fi - - -# Quick integrity check on total / index -if [[ "$TOTAL" -gt "24" ]]; then - echo "Invalid GROUP argument - $GROUP. Total groups must be be less than 24." - exit 1 -fi -if [[ "$INDEX" -lt "0" || "$INDEX" -ge "$TOTAL" ]]; then - echo "Invalid GROUP argument - $GROUP. INDEX must be positive and less than total." - exit 1 -fi - -# Determine the total number of operaitons in the list file -TOTAL_OPERATIONS=$(cat .lists/$LIST | wc -l | sed -e 's/ //g' ) - -# Divide the total operations by the total parts requrested to get group size -GROUP_SIZE=$(echo "$TOTAL_OPERATIONS $TOTAL" | awk '{print $1/$2}') -FLOOR_GROUP_SIZE=$(echo "$TOTAL_OPERATIONS $TOTAL" | awk '{print int($1/$2)}') -if [[ $GROUP_SIZE != $FLOOR_GROUP_SIZE ]]; then - echo "$TOTAL groups were requested and there are $TOTAL_OPERATIONS operations. Rounding group size up to ensure no operations are lost!" - GROUP_SIZE=$(($FLOOR_GROUP_SIZE+1)) -fi - -# Split file into N parts, which will produce files like $name-aa, $name-ab, etc... -# Next determine split files postfix. 97 is the ascii character code for 'a', by adding -# our current index to this value we will get the correct postfix of the file we want -# to target. -# -# Note that we limit the value of TOTAL to 24, which ensures no more than xaa - xaz -# file parts are created. -# -split -l $GROUP_SIZE .lists/$LIST .lists/$LIST- -SPLIT_FILE=a$(printf "\x$(printf %x $((97+$INDEX)))") -echo "Running operations in parallel" -echo " - Group: $((INDEX+1)) of $TOTAL." -echo " - Operation Count: $GROUP_SIZE" -echo " - Operation list: .lists/$LIST-$SPLIT_FILE" -echo " - Max Parallelization: ${MAX_JOBS}" - - -# Make sure the test folder exists in the artifacts dir -mkdir -p artifacts/tests - -if [[ -f .lists/$LIST-$SPLIT_FILE ]]; then - - # Provide some info about what is being run. This can be helpful in the event an operation hangs. - echo " - Conducting the following operations: " - cat .lists/$LIST-$SPLIT_FILE - - # This controls whether parallels writes to standard out immediately, or collects output and prints - # it all at once. When our max parallel jobs is set to 1, there is no reason to group output, and - # it's better to stream to stdout in real time. When our max parallel jobs are greater than 1, then - # streaming out results in interleaved output that is difficult to read. Another downside of group - # is that we may never see the output if a process crashes. - if [[ "$MAX_JOBS" == "-j 1" ]]; then - GROUP_ARG="--ungroup" - fi - - # Executes the command in the LIST file in parallel. Some notes on options - # Setting --load let's us wait for a heavy test suite to finish before starting another one - # Setting --joblog preserves the output in a log file. - parallel $MAX_JOBS $GROUP_ARG --load 50% --halt 0 --joblog artifacts/tests/$LIST-$SPLIT_FILE.log < .lists/$LIST-$SPLIT_FILE -else - # If there weren't enough commands to split up, then the file might not be present. For example, if there - # is just one operation to run, and we've requested to split operations into two groups, then second group - # will have zero operations and therefore nothing to run. - echo "Split test file, $LIST-$SPLIT_FILE, does not exist. Exiting early!" -fi diff --git a/.circleci/test-package.sh b/.circleci/test-package.sh index 61e7b1d36e..636d58b2fb 100755 --- a/.circleci/test-package.sh +++ b/.circleci/test-package.sh @@ -17,7 +17,7 @@ if grep -e "$MODULE" -e 'all' "$DIR/../packages/test.list" > /dev/null; then time ./scripts/test-ci.sh else # default action - time (NODE_ENV=test yarn workspace $MODULE $TEST) + time (NODE_ENV=test npx nx run $MODULE:$TEST) fi else echo -e "\n###################################" diff --git a/.eslintignore b/.eslintignore index 7a2fa3d67a..f935d5081f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ packages/fxa-auth-server/bin/ejs.js +packages/**/storybook-static diff --git a/.gitignore b/.gitignore index 47cb29fff7..d4f25ff322 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,6 @@ secrets.json .es5 .es5cache /artifacts -/packages/test.list .last-audit .eslintcache storybooks-publish @@ -163,3 +162,6 @@ configs/gql/allowlist # Next.js .next + + +tmp diff --git a/.nxignore b/.nxignore new file mode 100644 index 0000000000..62b9a7d9f6 --- /dev/null +++ b/.nxignore @@ -0,0 +1,5 @@ +**/.nyc_output +**/node_modules +**/browser_modules +**/.vscode +**/version.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 0d7fb4fe94..19e46f310f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,5 +21,14 @@ }, "python.pythonPath": "usr/bin/python3", "prettier.configPath": "_dev/.prettierrc", - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/storybook-static": true, + }, + "cSpell.words": [ + "Frontends" + ] } diff --git a/_dev/docker/ci/Dockerfile b/_dev/docker/ci/Dockerfile index f33971352d..0e0390b537 100644 --- a/_dev/docker/ci/Dockerfile +++ b/_dev/docker/ci/Dockerfile @@ -25,15 +25,7 @@ ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 ENV YARN_CHECKSUM_BEHAVIOR=throw ENV FXA_AUTO_INSTALL=0 RUN _scripts/l10n/clone.sh -RUN yarn install --immutable; \ - yarn gql:allowlist; \ - yarn workspaces foreach \ - -pv \ - --topological-dev \ - --include fxa-shared \ - --include fxa-auth-client \ - --include fxa-react \ - run build; +RUN yarn install --immutable; # Acts as an intermediate stage for adding the firefox install. Note, # that a yarn install must happen first to ensure the correct version diff --git a/_dev/docker/ci/Dockerfile.dockerignore b/_dev/docker/ci/Dockerfile.dockerignore index 14c37732f2..362146e3b8 100644 --- a/_dev/docker/ci/Dockerfile.dockerignore +++ b/_dev/docker/ci/Dockerfile.dockerignore @@ -12,6 +12,5 @@ **/artifacts **/configs **/temp - -!project/configs/gql/allowlist/ - +!**/configs/gql/allowlist +!**/packages/fxa-react/configs diff --git a/_dev/docker/mono/build.sh b/_dev/docker/mono/build.sh index 95128f0b30..a873b860b3 100755 --- a/_dev/docker/mono/build.sh +++ b/_dev/docker/mono/build.sh @@ -32,7 +32,7 @@ done # `npx yarn` because `npm i -g yarn` needs sudo npx yarn install npx yarn gql:allowlist -SKIP_PREFLIGHT_CHECK=true npx yarn workspaces foreach --topological-dev --verbose run build +SKIP_PREFLIGHT_CHECK=true npx nx run-many -t build --all --verbose # This will reduce packages to only production dependencies npx yarn workspaces focus --production --all diff --git a/_dev/pm2/start.sh b/_dev/pm2/start.sh index 84f669854b..9a7a3b6925 100755 --- a/_dev/pm2/start.sh +++ b/_dev/pm2/start.sh @@ -13,6 +13,7 @@ yarn gql:allowlist pm2 start _dev/pm2/infrastructure.config.js echo "waiting for containers to start" + _scripts/check-url.sh localhost:4100/health _scripts/check-url.sh localhost:9299/api/config _scripts/check-mysql.sh diff --git a/_scripts/check-url.sh b/_scripts/check-url.sh index 684666aead..90b51c5c34 100755 --- a/_scripts/check-url.sh +++ b/_scripts/check-url.sh @@ -1,9 +1,12 @@ #!/bin/bash -e +echo "Checking for response from: $1" + + RETRY=120 for i in $(eval echo "{1..$RETRY}"); do if [ "$(curl -s -o /dev/null --silent -w "%{http_code}" http://$1)" == "${2:-200}" ]; then - echo "$1 took $SECONDS seconds" + echo "$1 responded in $SECONDS seconds" exit 0 else if [ "$i" -lt $RETRY ]; then @@ -11,5 +14,5 @@ for i in $(eval echo "{1..$RETRY}"); do fi fi done -echo "giving up after $SECONDS seconds" +echo "Giving up after $SECONDS seconds. Failed to get response from: $1" exit 1 diff --git a/_scripts/pm2-all.sh b/_scripts/pm2-all.sh index d44eeaf108..cc1e6fc46e 100755 --- a/_scripts/pm2-all.sh +++ b/_scripts/pm2-all.sh @@ -1,5 +1,7 @@ #!/bin/bash -e +start=`date +%s` + DIR=$(dirname "$0") COMMAND=$1 cd "$DIR/.." @@ -10,23 +12,11 @@ then fi mkdir -p artifacts +npx nx run-many -t start --all --exclude=fxa-dev-launcher --verbose; -echo "building shared fxa projects..." -if ! nx run-many --targets=fxa-auth-client,fxa-react,fxa-shared --all build --verbose > artifacts/build-shared.log; -then - echo -e "\n###########################################################\n" - echo "# fxa couldn't build shared projects. see ./artifacts/build-shared.log for details" - echo -e "\n###########################################################\n" - exit 1 -fi +end=`date +%s` +runtime=$((end-start)) -echo "${COMMAND} fxa services and nx projects..." -if nx run-many --verbose --exclude fxa-dev-launcher --exclude fxa --targets="$COMMAND" > artifacts/start.log; -then - pm2 ls -else - echo -e "\n###########################################################\n" - echo "# fxa couldn't start. see ./artifacts/start.log for details" - echo -e "\n###########################################################\n" - exit 1 -fi +echo -e "\n###########################################################\n" +echo "# Stack Started Successfully ! ${runtime}s" +echo -e "\n###########################################################\n" diff --git a/apps/payments/next/project.json b/apps/payments/next/project.json index cd32729df7..d4244eb312 100644 --- a/apps/payments/next/project.json +++ b/apps/payments/next/project.json @@ -79,5 +79,5 @@ "command": "pm2 delete apps/payments/next/pm2.config.js" } }, - "tags": ["lib", "payments"] + "tags": ["app", "payments"] } diff --git a/libs/payments/cart/project.json b/libs/payments/cart/project.json index 1ad042f3a2..c31253365a 100644 --- a/libs/payments/cart/project.json +++ b/libs/payments/cart/project.json @@ -37,5 +37,5 @@ } } }, - "tags": ["lib", "payments"] + "tags": ["scope:shared:lib:payments"] } diff --git a/libs/payments/paypal/project.json b/libs/payments/paypal/project.json index c73760f743..68ef993cb4 100644 --- a/libs/payments/paypal/project.json +++ b/libs/payments/paypal/project.json @@ -38,5 +38,5 @@ } } }, - "tags": ["lib", "payments"] + "tags": ["scope:shared:lib:payments"] } diff --git a/libs/shared/db/mysql/account/project.json b/libs/shared/db/mysql/account/project.json index 078a1864d9..fba9a67bb3 100644 --- a/libs/shared/db/mysql/account/project.json +++ b/libs/shared/db/mysql/account/project.json @@ -38,5 +38,5 @@ } } }, - "tags": ["lib", "shared"] + "tags": ["scope:shared:lib"] } diff --git a/libs/shared/db/mysql/core/project.json b/libs/shared/db/mysql/core/project.json index 85a5f53c79..c3b7810d00 100644 --- a/libs/shared/db/mysql/core/project.json +++ b/libs/shared/db/mysql/core/project.json @@ -38,5 +38,5 @@ } } }, - "tags": ["lib", "shared"] + "tags": ["scope:shared:lib"] } diff --git a/libs/shared/error/project.json b/libs/shared/error/project.json index 4f8695a467..6379dbc86e 100644 --- a/libs/shared/error/project.json +++ b/libs/shared/error/project.json @@ -37,5 +37,5 @@ } } }, - "tags": ["lib", "shared"] + "tags": ["scope:shared:lib"] } diff --git a/libs/shared/log/project.json b/libs/shared/log/project.json index ce53188064..8dd6c68402 100644 --- a/libs/shared/log/project.json +++ b/libs/shared/log/project.json @@ -38,5 +38,5 @@ } } }, - "tags": ["lib", "shared"] + "tags": ["scope:shared:lib"] } diff --git a/libs/shared/metrics/statsd/project.json b/libs/shared/metrics/statsd/project.json index 51d46d490d..f42c46d034 100644 --- a/libs/shared/metrics/statsd/project.json +++ b/libs/shared/metrics/statsd/project.json @@ -38,5 +38,5 @@ } } }, - "tags": ["lib", "shared"] + "tags": ["scope:shared:lib"] } diff --git a/nx.json b/nx.json index af9e780920..062f368c39 100644 --- a/nx.json +++ b/nx.json @@ -5,33 +5,161 @@ "default": { "runner": "nx-cloud", "options": { - "cacheableOperations": ["build", "lint", "test-unit", "test-integration", "e2e"], + "cacheableOperations": [ + "build", + "build-l10n", + "build-storybook", + "compile", + "gql-copy", + "gql-extract", + "lint", + "prebuild", + "test-e2e", + "test-integration", + "test-unit" + ], "accessToken": "YzRhMzhiNjEtODE0OS00Njg1LTg2NDktMGJlZjBjNmJjMTc1fHJlYWQtb25seQ==" } } }, "targetDefaults": { "build": { - "dependsOn": ["^build"], - "inputs": ["production", "^production"] + "dependsOn": ["prebuild", "^build"], + "inputs": ["production", "^production"], + "outputs": [ + "{projectRoot}/*.tsbuildinfo", + "{projectRoot}/*/.tmp", + "{projectRoot}/**/*.d.ts", + "{projectRoot}/app/i18n", + "{projectRoot}/build", + "{projectRoot}/dist", + "{projectRoot}/lib/senders/emails/css", + "{projectRoot}/locale", + "{projectRoot}/public", + "{projectRoot}/src/styles/*.css", + "{projectRoot}/test/**/*.ftl", + "{projectRoot}/test/**/client.json" + ] + }, + "build-storybook": { + "dependsOn": ["build"], + "inputs": ["production", "^production"], + "outputs": ["{projectRoot}/storybook-static"] + }, + "compile": { + "dependsOn": ["^compile"], + "inputs": ["typescript", "^typescript"], + "outputs": ["{projectRoot}/build", "{projectRoot}/dist"] + }, + "gql-copy": { + "dependsOn": [ + { + "projects": ["fxa-settings", "fxa-admin-panel"], + "target": "gql-extract" + } + ], + "inputs": ["typescript", "^typescript"], + "outputs": ["{projectRoot}/src/config/gql/allowlist"] + }, + "gql-extract": { + "dependsOn": [], + "inputs": ["typescript"], + "outputs": ["{workspaceRoot}/configs/gql/allowlist"] }, "lint": { - "inputs": ["default", "{workspaceRoot}/.eslintrc.json"] + "inputs": ["lint", "{workspaceRoot}/.eslintrc.json"], + "outputs": ["{projectRoot}/.eslintcache"] + }, + "prebuild": { + "dependsOn": ["gql-copy"], + "inputs": [], + "outputs": [ + "{projectRoot}/public/locales", + "{projectRoot}/public/legal-docs", + "{projectRoot}/server/config/local.json", + "{projectRoot}/var", + "{projectRoot}/vendor/ejs.js", + "{workspaceRoot}/external/l10n", + "{workspaceRoot}/external/legal-docs" + ] + }, + "restart": { + "dependsOn": ["build", "^restart"], + "inputs": ["production", "^production"], + "outputs": [] + }, + "start": { + "dependsOn": ["build", "gen-keys", "^start"], + "inputs": ["production", "^production"], + "outputs": [] + }, + "storybook": { + "dependsOn": ["build"], + "inputs": ["production", "^production"], + "outputs": ["{projectRoot}/storybook-static"] + }, + "test": { + "inputs": ["production", "^production"], + "dependsOn": ["test-unit", "test-integration", "test-e2e"], + "outputs": [ + "{projectRoot}/coverage", + "{projectRoot}/.nyc_output", + "{projectRoot}/test-results.xml" + ] + }, + "test-e2e": { + "dependsOn": ["build"], + "inputs": ["production", "^production"], + "outputs": [ + "{projectRoot}/coverage", + "{projectRoot}/.nyc_output", + "{projectRoot}/test-results.xml" + ] + }, + "test-integration": { + "dependsOn": ["build", "gen-keys"], + "inputs": ["test", "^test"], + "outputs": [ + "{projectRoot}/coverage", + "{projectRoot}/.nyc_output", + "{projectRoot}/test-results.xml", + "{projectRoot}/test/scripts/test_output" + ] }, "test-unit": { - "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"] + "dependsOn": ["build", "gen-keys"], + "inputs": ["test", "^test"], + "outputs": [ + "{projectRoot}/coverage", + "{projectRoot}/.nyc_output", + "{projectRoot}/test-results.xml" + ] } }, "namedInputs": { - "default": ["{projectRoot}/**/*", "sharedGlobals"], + "default": ["{projectRoot}/**/*.*", "sharedGlobals"], + "lint": ["{projectRoot}/**/*.@(js|jsx|ts|tsx)"], "production": [ "default", + "{workspaceRoot}/external/l10n/**/*.ftl", + "{workspaceRoot}/external/legal-docs/**/*.md", "!{projectRoot}/.eslintrc.json", - "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", - "!{projectRoot}/tsconfig.spec.json", - "!{projectRoot}/jest.config.[jt]s" + "!{projectRoot}/.storybook/**/*", + "!{projectRoot}/**/test/**/*", + "!{projectRoot}/**/tests/**/*", + "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx)", + "!{projectRoot}/**/*.(spec|test).@(js|jsx|ts|tsx)", + "!{projectRoot}/jest.config.@(js|ts)", + "!{projectRoot}/tsconfig.+(spec|storybook).json" ], - "sharedGlobals": [] + "sharedGlobals": [{ "runtime": "node -v" }, { "runtime": "tsc -v" }], + "test": ["default", "{workspaceRoot}/jest.preset.js"], + "typescript": [ + "{projectRoot}/**/*.@(ts|tsx)", + "{projectRoot}/package.json", + "{projectRoot}/tsconfig.*", + "sharedGlobals" + ] }, "cli": { "packageManager": "yarn" diff --git a/package.json b/package.json index fd8b76543d..15122e6ab8 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "stop": "nps --prefix=stop", "restart": "nps --prefix=restart", "delete": "nps --prefix=delete", - "rebuild-packages": "yarn workspaces foreach run build", + "rebuild-packages": "nx run-many -t build --all", "adb-reverse": "./_scripts/adb-reverse.sh", "test": "_scripts/test-package.sh", "config-fxios": "node _scripts/config-fxios.js", @@ -24,7 +24,9 @@ "l10n:prime": "_scripts/l10n/prime.sh", "l10n:bundle": "_scripts/l10n/bundle.sh", "legal:clone": "_scripts/clone-legal-docs.sh", - "gql:allowlist": "nx run-many -t extract-gql && nx run-many -t copy-gql" + "gql:allowlist": "nx run-many -t gql-extract && nx run-many -t gql-copy", + "check:mysql": "_scripts/check-mysql.sh", + "check:url": "_scripts/check-url.sh" }, "homepage": "https://github.com/mozilla/fxa", "bugs": { diff --git a/packages/123done/package.json b/packages/123done/package.json index 49d3dab23a..de27fcfe23 100644 --- a/packages/123done/package.json +++ b/packages/123done/package.json @@ -44,5 +44,10 @@ "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", "format": "prettier --write --config ../../_dev/.prettierrc '**'" + }, + "nx": { + "tags": [ + "scope:demo" + ] } } diff --git a/packages/browserid-verifier/package.json b/packages/browserid-verifier/package.json index 028bb19df1..95af0bab0c 100644 --- a/packages/browserid-verifier/package.json +++ b/packages/browserid-verifier/package.json @@ -50,5 +50,10 @@ "stop": "pm2 stop pm2.config.js", "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js" + }, + "nx": { + "tags": [ + "scope:server" + ] } } diff --git a/packages/eslint-plugin-fxa/package.json b/packages/eslint-plugin-fxa/package.json index 78ed45a0ed..8da3ab1487 100644 --- a/packages/eslint-plugin-fxa/package.json +++ b/packages/eslint-plugin-fxa/package.json @@ -4,7 +4,8 @@ "description": "eslint plugin for Firefox Accounts", "main": "lib/index.js", "scripts": { - "test": "mocha" + "test": "mocha", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "dependencies": { "eslint": "6.6.0", @@ -26,5 +27,10 @@ "bugs": { "url": "https://github.com/mozilla/fxa/issues" }, - "homepage": "https://github.com/mozilla/fxa" + "homepage": "https://github.com/mozilla/fxa", + "nx": { + "tags": [ + "scope:shared:plugin" + ] + } } diff --git a/packages/fortress/package.json b/packages/fortress/package.json index 8ded163c7a..91fcf65977 100644 --- a/packages/fortress/package.json +++ b/packages/fortress/package.json @@ -44,5 +44,10 @@ "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", "format": "prettier --write --config ../../_dev/.prettierrc '**'" + }, + "nx": { + "tags": [ + "scope:demo" + ] } } diff --git a/packages/functional-tests/package.json b/packages/functional-tests/package.json index 1aab56874d..74810080dc 100644 --- a/packages/functional-tests/package.json +++ b/packages/functional-tests/package.json @@ -3,11 +3,13 @@ "version": "0.0.0", "private": true, "scripts": { + "clean": "rimraf dist", "record": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=stub --debug", "test": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=local", "test-local": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=local", "test-stage": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=stage", - "test-production": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=production" + "test-production": "NODE_OPTIONS='--dns-result-order=ipv4first' playwright test --project=production", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "devDependencies": { "@playwright/test": "^1.34.1", @@ -19,5 +21,10 @@ "jsqr": "^1.4.0", "pdf-parse": "^1.1.1", "upng-js": "^2.1.0" + }, + "nx": { + "tags": [ + "scope:functional-test" + ] } } diff --git a/packages/functional-tests/scripts/start-services.sh b/packages/functional-tests/scripts/start-services.sh index ad08a96920..dee9a39dfa 100755 --- a/packages/functional-tests/scripts/start-services.sh +++ b/packages/functional-tests/scripts/start-services.sh @@ -9,7 +9,13 @@ cd "$DIR/../../../" mkdir -p ~/.pm2/logs mkdir -p artifacts/tests -CI=true npx nx run-many -p \ + +# Make sure we have built the latest +CI=false NODE_ENV=test npx nx run-many \ + -t start \ + --parallel=1 \ + --verbose \ + -p \ 123done \ browserid-verifier \ fxa-auth-server \ @@ -18,16 +24,6 @@ CI=true npx nx run-many -p \ fxa-payments-server \ fxa-profile-server \ fxa-settings \ - -t start > ~/.pm2/logs/startup.log - -# stop services that aren't needed. These are 'watching' services, and they just -# consume memory. Ideally, we wouldn't even start these, but they are baked into -# the pm2 config start up. -npx pm2 stop auth-ftl & -npx pm2 stop settings-css & -npx pm2 stop settings-ftl & -npx pm2 stop payments-css & -npx pm2 stop payments-ftl & -wait + > ~/.pm2/logs/startup.log npx pm2 ls diff --git a/packages/fxa-admin-panel/package.json b/packages/fxa-admin-panel/package.json index c4123d8934..f3c4b186a7 100644 --- a/packages/fxa-admin-panel/package.json +++ b/packages/fxa-admin-panel/package.json @@ -3,24 +3,25 @@ "version": "0.0.0", "description": "FxA Admin Panel", "scripts": { + "build": "yarn build-ts-server && yarn build-ts-client && yarn build-css && yarn build-react", + "build-ts-client": "tsc --build", + "build-ts-server": "tsc -p server/tsconfig.json", "build-css": "npx tailwindcss -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css --postcss", - "build-client": "tsc --build ../fxa-react && tsc --build && NODE_ENV=production yarn build-css && SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false CI=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", - "build-server": "tsc -p server/tsconfig.json", - "extract-gql": "persistgraphql src ../../configs/gql/allowlist/fxa-admin-panel.json --js --extension=ts", - "build": "yarn build-client && yarn build-server", + "build-react": "SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false CI=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", + "clean": "rimraf dist", "compile": "tsc --noEmit", "eject": "react-scripts eject", "format": "prettier --write --config ../../_dev/.prettierrc '**'", + "gql-extract": "persistgraphql src ../../configs/gql/allowlist/fxa-admin-panel.json --js --extension=ts", "lint": "eslint .", - "restart": "tsc --build ../fxa-react && yarn build-css && pm2 restart pm2.config.js", - "start": "tsc --build ../fxa-react && yarn build-css && pm2 start pm2.config.js", + "restart": "pm2 restart pm2.config.js", + "start": "pm2 start pm2.config.js", "stop": "pm2 stop pm2.config.js", "delete": "pm2 delete pm2.config.js", + "test": "yarn test-unit", "test-frontend": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-frontend.xml SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test --coverage --verbose --ci --reporters=default --reporters=jest-junit -t '^(?!.*#integration)'", "test-server": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-server.xml jest --runInBand --coverage --verbose --config server/jest.config.js --forceExit --ci --reporters=default --reporters=jest-junit -t '^(?!.*#integration)'", - "test": "CI=true yarn test-frontend && CI=true yarn test-server", - "test-unit": "yarn build-css && yarn build-client && yarn test", - "test-integration": "echo No integration tests present for $npm_package_name" + "test-unit": "CI=true yarn test-frontend && CI=true yarn test-server" }, "browserslist": { "production": [ @@ -86,5 +87,10 @@ "ts-jest": "^29.1.0", "typescript": "^5.2.2", "webpack": "^5.84.1" + }, + "nx": { + "tags": [ + "scope:frontend" + ] } } diff --git a/packages/fxa-admin-panel/scripts/test-ci.sh b/packages/fxa-admin-panel/scripts/test-ci.sh index a3799e0c2c..855e7a6092 100755 --- a/packages/fxa-admin-panel/scripts/test-ci.sh +++ b/packages/fxa-admin-panel/scripts/test-ci.sh @@ -1,4 +1,4 @@ #!/bin/bash -ex -yarn build -NODE_ENV=test yarn test +npx nx fxa-admin-panel:build +NODE_ENV=test npx nx fxa-admin-panel:test diff --git a/packages/fxa-admin-server/package.json b/packages/fxa-admin-server/package.json index 15a1d97366..c2c4de8059 100644 --- a/packages/fxa-admin-server/package.json +++ b/packages/fxa-admin-server/package.json @@ -3,14 +3,15 @@ "version": "0.0.0", "description": "FxA GraphQL Admin Server", "scripts": { - "prebuild": "rimraf dist && yarn gql:allowlist", - "copy-gql": "mkdir -p src/config/gql/allowlist && cp ../../configs/gql/allowlist/*.json src/config/gql/allowlist/.", + "prebuild": "yarn clean", + "gql-copy": "mkdir -p src/config/gql/allowlist/ && cp ../../configs/gql/allowlist/*.json src/config/gql/allowlist/.", + "build": "nest build && yarn copy-config && yarn gql-copy", "copy-config": "cp ./src/config/*.json ./dist/packages/fxa-admin-server/src/config", - "build": "yarn prebuild && nest build && yarn copy-config", + "clean": "rimraf dist", "compile": "tsc --noEmit", "lint": "eslint .", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", - "start": "yarn build && pm2 start pm2.config.js", + "start": "pm2 start pm2.config.js", "stop": "pm2 stop pm2.config.js", "start-prod": "node dist/packages/fxa-graphql-api/src/main", "restart": "pm2 restart pm2.config.js", @@ -104,5 +105,10 @@ }, "coverageDirectory": "../coverage", "testEnvironment": "node" + }, + "nx": { + "tags": [ + "scope:server" + ] } } diff --git a/packages/fxa-admin-server/pm2.config.js b/packages/fxa-admin-server/pm2.config.js index 20b8fc864a..303ec09c5a 100644 --- a/packages/fxa-admin-server/pm2.config.js +++ b/packages/fxa-admin-server/pm2.config.js @@ -8,8 +8,8 @@ const PATH = process.env.PATH.split(':') const nest = require.resolve('@nestjs/cli/bin/nest.js'); const getDevScript = () => `${nest} start --debug=9150 --watch`; -const getProdScript = () => - 'rm -rf dist && yarn build && node dist/packages/fxa-admin-server/src/main.js'; +const getProdScript = () => 'node dist/packages/fxa-admin-server/src/main.js'; + const script = process.env.CI === 'true' || process.env.NODE_ENV === 'production' ? getProdScript() diff --git a/packages/fxa-auth-client/package.json b/packages/fxa-auth-client/package.json index 2bcf698276..752ea589ab 100644 --- a/packages/fxa-auth-client/package.json +++ b/packages/fxa-auth-client/package.json @@ -34,10 +34,10 @@ }, "scripts": { "lint": "eslint . --ext .ts", - "postinstall": "(tsc --build tsconfig.browser.json && tsc --build && tsc --build tsconfig.cjs.json) || true", - "build": "tsc --build tsconfig.browser.json && tsc --build && tsc --build tsconfig.cjs.json", - "compile": "tsc --noEmit", - "ts-check": "tsc --noEmit", + "build": "yarn build-ts", + "build-ts": "tsc --build tsconfig.browser.json && tsc --build tsconfig.cjs.json && tsc --build", + "clean": "rimraf dist", + "compile": "yarn build-ts", "test": "mocha -r esbuild-register test/*", "format": "prettier --write --config ../../_dev/.prettierrc '**'", "test-unit": "MOCHA_FILE=../../artifacts/tests/$npm_package_name/mocha-unit.xml mocha -r esbuild-register test/*", @@ -72,5 +72,10 @@ "mocha": { "reporter": "mocha-multi", "reporterOptions": "spec=-,mocha-junit-reporter=-" + }, + "nx": { + "tags": [ + "scope:shared:lib" + ] } } diff --git a/packages/fxa-auth-server/package.json b/packages/fxa-auth-server/package.json index cc715a8ff7..b1477520c7 100644 --- a/packages/fxa-auth-server/package.json +++ b/packages/fxa-auth-server/package.json @@ -9,30 +9,37 @@ "test": "test" }, "scripts": { - "build": "yarn merge-ftl && yarn emails-scss && tsc --build && tsc-alias && cp -R config public lib scripts dist/packages/fxa-auth-server", - "clean": "git clean -fXd", + "prebuild": "nx l10n-prime && nx install-ejs", + "build": "nx build-l10n && nx build-ts && nx build-css && nx build-finalize", + "build-l10n": "nx l10n-merge && nx l10n-merge-test", + "build-css": "nx emails-scss", + "build-ts": "tsc --build && tsc-alias", + "build-finalize": "cp -R config public lib scripts dist/packages/fxa-auth-server", + "build-storybook": "NODE_OPTIONS=--openssl-legacy-provider STORYBOOK_BUILD=true storybook build && yarn build-storybook-copy-locales && yarn build-storybook-copy-templates", + "build-storybook-copy-locales": "mkdir -p ./storybook-static/public/locales && cp -R ./public/locales ./storybook-static/public", + "build-storybook-copy-templates": "mkdir -p ./storybook-static/lib/senders/emails/templates && cp -R ./lib/senders/emails ./storybook-static/lib/senders", + "bump-template-versions": "node scripts/template-version-bump", + "clean": "rimraf dist", + "clean-up-old-ci-stripe-customers": "node -r esbuild-register ./scripts/clean-up-old-ci-stripe-customers.js --limit 1000", "compile": "tsc --noEmit", "create-mock-iap": "NODE_ENV=dev FIRESTORE_EMULATOR_HOST=localhost:9090 node -r esbuild-register ./scripts/create-mock-iap-subscriptions.ts", - "bump-template-versions": "node scripts/template-version-bump", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", "glean-generate": "yarn glean translate ../fxa-shared/metrics/glean/fxa-backend-pings.yaml ../fxa-shared/metrics/glean/fxa-backend-metrics.yaml -f typescript_server -o lib/metrics/glean", "glean-lint": "yarn glean glinter ../fxa-shared/metrics/glean/fxa-backend-pings.yaml ../fxa-shared/metrics/glean/fxa-backend-metrics.yaml", "l10n-prime": "yarn l10n:prime fxa-auth-server", + "l10n-merge": "yarn grunt merge-ftl", + "l10n-merge-test": "yarn grunt merge-ftl:test", + "l10n-watch": "yarn grunt watch-ftl", "lint": "yarn glean-lint && eslint . .storybook --ext .js,.ts", - "start": "yarn merge-ftl && yarn emails-scss && scripts/start-local.sh", - "stop": "pm2 stop pm2.config.js", - "restart": "pm2 restart pm2.config.js", - "delete": "pm2 delete pm2.config.js", - "test": "yarn merge-ftl-test && yarn emails-scss && VERIFIER_VERSION=0 scripts/test-local.sh", - "test-ci": "yarn merge-ftl-test && scripts/test-local.sh && yarn test-e2e", - "test-unit": "yarn merge-ftl-test && yarn emails-scss && VERIFIER_VERSION=0 TEST_TYPE=unit scripts/test-ci.sh", - "test-integration": "yarn merge-ftl-test && yarn emails-scss && VERIFIER_VERSION=0 TEST_TYPE=integration scripts/test-ci.sh", - "test-e2e": "NODE_ENV=dev mocha -r esbuild-register test/e2e", - "test-scripts": "NODE_ENV=dev mocha -r esbuild-register test/scripts --exit", - "test-remote": "MAILER_HOST=restmail.net MAILER_PORT=80 CORS_ORIGIN=http://baz mocha -r esbuild-register --timeout=300000 test/remote", - "format": "prettier --write --config ../../_dev/.prettierrc '**'", + "install-ejs": "./scripts/install-ejs.sh", "gen-keys": "node -r esbuild-register ./scripts/gen_keys.js; node -r esbuild-register ./scripts/oauth_gen_keys.js; node -r esbuild-register ./scripts/gen_vapid_keys.js", - "clean-up-old-ci-stripe-customers": "node -r esbuild-register ./scripts/clean-up-old-ci-stripe-customers.js --limit 1000", + "emails-scss": "node -r esbuild-register ./lib/senders/emails/sass-compile-files.ts", + "format": "prettier --write --config ../../_dev/.prettierrc '**'", + "start": "yarn check:mysql && pm2 start pm2.config.js && yarn check:url localhost:9000/__heartbeat__", + "restart": "pm2 restart pm2.config.js", + "test": "VERIFIER_VERSION=0 scripts/test-local.sh", + "test-unit": "VERIFIER_VERSION=0 TEST_TYPE=unit scripts/test-ci.sh", + "test-integration": "VERIFIER_VERSION=0 TEST_TYPE=integration scripts/test-ci.sh", "populate-firestore-customers": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/populate-firestore-customers.ts", "populate-vat-taxes": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/populate-vat-taxes.ts", "paypal-processor": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/paypal-processor.ts", @@ -40,15 +47,10 @@ "subscription-reminders": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/subscription-reminders.ts", "audit-orphaned-stripe-accounts": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/audit-orphaned-customers.ts", "remove-unverified-accounts": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/remove-unverified-accounts.ts", - "emails-scss": "node -r esbuild-register ./lib/senders/emails/sass-compile-files.ts", - "storybook": "yarn l10n-prime && yarn install-ejs && yarn emails-scss && NODE_OPTIONS=--openssl-legacy-provider storybook dev -p 6010 --no-version-updates ", - "build-storybook": "yarn l10n-prime && yarn install-ejs && yarn emails-scss && NODE_OPTIONS=--openssl-legacy-provider STORYBOOK_BUILD=true storybook build && yarn build-storybook-copy-locales && yarn build-storybook-copy-templates", - "build-storybook-copy-locales": "mkdir -p ./storybook-static/public/locales && cp -R ./public/locales ./storybook-static/public", - "build-storybook-copy-templates": "mkdir -p ./storybook-static/lib/senders/emails/templates && cp -R ./lib/senders/emails ./storybook-static/lib/senders", - "install-ejs": "./scripts/install-ejs.sh", - "merge-ftl": "yarn l10n-prime && grunt merge-ftl", - "merge-ftl-test": "yarn l10n-prime && grunt merge-ftl:test", - "watch-ftl": "yarn grunt watch-ftl" + "storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6010 --no-version-updates -s ./", + "merge-ftl": "nx l10n-merge", + "merge-ftl-test": "nx l10n-merge", + "watch-ftl": "nx l10n-watch" }, "repository": { "type": "git", @@ -231,5 +233,10 @@ "mocha": { "reporter": "mocha-multi", "reporterOptions": "spec=-,mocha-junit-reporter=-" + }, + "nx": { + "tags": [ + "scope:server:auth" + ] } } diff --git a/packages/fxa-auth-server/pm2.config.js b/packages/fxa-auth-server/pm2.config.js index 58f90a6fd7..bf39f2a1e1 100644 --- a/packages/fxa-auth-server/pm2.config.js +++ b/packages/fxa-auth-server/pm2.config.js @@ -6,60 +6,65 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); +const apps = [ + { + name: 'auth', + script: 'node -r esbuild-register bin/key_server.js', + cwd: __dirname, + env: { + DB: 'mysql', + NODE_ENV: 'dev', + NODE_OPTIONS: '--inspect=9160 --dns-result-order=ipv4first', + TS_NODE_TRANSPILE_ONLY: 'true', + IP_ADDRESS: '0.0.0.0', + SIGNIN_UNBLOCK_FORCED_EMAILS: '^block.*@restmail\\.net$', + SIGNIN_CONFIRMATION_ENABLED: 'true', + SIGNIN_CONFIRMATION_FORCE_EMAIL_REGEX: '^sync.*@restmail\\.net$', + FIRESTORE_EMULATOR_HOST: 'localhost:9090', + FORCE_PASSWORD_CHANGE_EMAIL_REGEX: 'forcepwdchange', + CONFIG_FILES: 'config/secrets.json', + EMAIL_CONFIG_USE_REDIS: 'false', + PORT: '9000', + PATH, + SENTRY_ENV: 'local', + SENTRY_DSN: process.env.SENTRY_DSN_AUTH, + TRACING_SERVICE_NAME: 'fxa-auth-server', + }, + filter_env: ['npm_'], + watch: ['bin', 'config', 'lib'], + max_restarts: '1', + min_uptime: '2m', + time: true, + }, + { + name: 'inbox', + script: 'node -r esbuild-register test/mail_helper.js', + cwd: __dirname, + env: { + NODE_ENV: 'dev', + NODE_OPTIONS: '--dns-result-order=ipv4first', + MAILER_PORT: '9001', + PATH, + }, + filter_env: ['npm_'], + max_restarts: '1', + min_uptime: '2m', + time: true, + }, +]; + +if (process.env.CI !== 'true') { + apps.push({ + name: 'auth-ftl', + script: 'yarn grunt watch-ftl', + cwd: __dirname, + filter_env: ['npm_'], + max_restarts: '1', + min_uptime: '2m', + time: true, + }); +} + module.exports = { - apps: [ - { - name: 'auth', - script: 'node -r esbuild-register bin/key_server.js', - cwd: __dirname, - env: { - DB: 'mysql', - NODE_ENV: 'dev', - NODE_OPTIONS: '--inspect=9160 --dns-result-order=ipv4first', - TS_NODE_TRANSPILE_ONLY: 'true', - IP_ADDRESS: '0.0.0.0', - SIGNIN_UNBLOCK_FORCED_EMAILS: '^block.*@restmail\\.net$', - SIGNIN_CONFIRMATION_ENABLED: 'true', - SIGNIN_CONFIRMATION_FORCE_EMAIL_REGEX: '^sync.*@restmail\\.net$', - FIRESTORE_EMULATOR_HOST: 'localhost:9090', - FORCE_PASSWORD_CHANGE_EMAIL_REGEX: 'forcepwdchange', - CONFIG_FILES: 'config/secrets.json', - EMAIL_CONFIG_USE_REDIS: 'false', - PORT: '9000', - PATH, - SENTRY_ENV: 'local', - SENTRY_DSN: process.env.SENTRY_DSN_AUTH, - TRACING_SERVICE_NAME: 'fxa-auth-server', - }, - filter_env: ['npm_'], - watch: ['bin', 'config', 'lib'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - { - name: 'auth-ftl', - script: 'yarn grunt watch-ftl', - cwd: __dirname, - filter_env: ['npm_'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - { - name: 'inbox', - script: 'node -r esbuild-register test/mail_helper.js', - cwd: __dirname, - env: { - NODE_ENV: 'dev', - NODE_OPTIONS: '--dns-result-order=ipv4first', - MAILER_PORT: '9001', - PATH, - }, - filter_env: ['npm_'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - ], + apps, }; diff --git a/packages/fxa-auth-server/scripts/start-local.sh b/packages/fxa-auth-server/scripts/start-local.sh deleted file mode 100755 index 1fe1fb0778..0000000000 --- a/packages/fxa-auth-server/scripts/start-local.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -e - -export NODE_ENV=dev - -yarn gen-keys -../../_scripts/check-mysql.sh -pm2 start pm2.config.js - -../../_scripts/check-url.sh localhost:9000/__heartbeat__ diff --git a/packages/fxa-auth-server/scripts/test-ci.sh b/packages/fxa-auth-server/scripts/test-ci.sh index 5f6e71a17b..a047326d3c 100755 --- a/packages/fxa-auth-server/scripts/test-ci.sh +++ b/packages/fxa-auth-server/scripts/test-ci.sh @@ -10,20 +10,13 @@ DEFAULT_ARGS="--require esbuild-register --require tsconfig-paths/register --rec if [ "$TEST_TYPE" == 'unit' ]; then GREP_TESTS="--grep #integration --invert "; fi; if [ "$TEST_TYPE" == 'integration' ]; then GREP_TESTS="--grep #integration "; fi; -node -r esbuild-register ./scripts/gen_keys.js -node -r esbuild-register ./scripts/gen_vapid_keys.js -node -r esbuild-register ./scripts/oauth_gen_keys.js - -echo 'Updating ftl files' -# Migrate current strings -yarn run merge-ftl -yarn run merge-ftl-test - -# Process sass for rendering of email templates -echo -yarn run emails-scss TESTS=(local oauth remote scripts) +if [ -z "$1" ]; then + TESTS=(local oauth remote scripts) +else + TESTS=($1) +fi for t in "${TESTS[@]}"; do echo -e "\n\nTesting: $t" diff --git a/packages/fxa-content-server/package.json b/packages/fxa-content-server/package.json index 1b639f240d..a7f81cc7aa 100644 --- a/packages/fxa-content-server/package.json +++ b/packages/fxa-content-server/package.json @@ -3,24 +3,28 @@ "version": "0.0.0", "description": "Firefox Accounts Content Server", "scripts": { - "build": "tsc --build ../fxa-react && yarn l10n-prime && yarn build-css && NODE_ENV=production grunt build", - "build-css": "npx tailwindcss --postcss -i ./app/styles/tailwind.css -o ./app/styles/tailwind.out.css", + "prebuild": "yarn l10n-prime && yarn copy-local-config && yarn check-local-config ", + "build": "yarn build-l10n && yarn build-css && yarn build-js", + "build-css": "tailwindcss --postcss -i ./app/styles/tailwind.css -o ./app/styles/tailwind.out.css", + "build-js": "NODE_ENV=production grunt build", + "build-l10n": "yarn l10n-create-json", + "check-local-config": "node scripts/check-local-config", + "clean": "rimraf dist", "compile": "tsc --noEmit", - "clean": "git clean -fXd", + "copy-local-config": "cp server/config/local.json-dist server/config/local.json", "glean-generate": "yarn glean translate ../fxa-shared/metrics/glean/fxa-ui-pings.yaml ../fxa-shared/metrics/glean/fxa-ui-metrics.yaml -f javascript -o app/scripts/lib/glean", - "glean-lint": "yarn glean glinter ../fxa-shared/metrics/glean/fxa-ui-pings.yaml ../fxa-shared/metrics/glean/fxa-ui-metrics.yaml", - "postinstall": "cp server/config/local.json-dist server/config/local.json", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", + "l10n-create-json": "NODE_OPTIONS=--openssl-legacy-provider grunt l10n-create-json", "l10n-prime": "yarn l10n:prime fxa-content-server", - "lint": "yarn glean-lint && eslint app server tests --cache", - "start": "node scripts/check-local-config && yarn l10n-prime && NODE_OPTIONS=--openssl-legacy-provider grunt l10n-create-json && pm2 start pm2.config.js && ../../_scripts/check-url.sh localhost:3030/bundle/app.bundle.js && yarn build-css", + "lint": "yarn lint-glean && eslint app server tests --cache", + "lint-glean": "yarn glean glinter ../fxa-shared/metrics/glean/fxa-ui-pings.yaml ../fxa-shared/metrics/glean/fxa-ui-metrics.yaml", + "start": "pm2 start pm2.config.js && yarn check:url localhost:3030/bundle/app.bundle.js", "stop": "pm2 stop pm2.config.js", - "restart": "pm2 restart pm2.config.js && yarn build-css", + "restart": "pm2 restart pm2.config.js ", "delete": "pm2 delete pm2.config.js", "start-production": "NODE_ENV=production grunt build && yarn build-css && CONFIG_FILES=server/config/local.json,server/config/production.json,server/config/secrets.json grunt serverproc:dist", "start-remote": "scripts/run_remote_dev.sh", "test": "node tests/intern.js --unit=true", - "test-circle": "node tests/intern.js --suites=circle --fxaAuthRoot=https://fxaci.dev.lcip.org/auth --fxaEmailRoot=http://restmail.net --fxaOAuthApp=https://oauth-fxaci.dev.lcip.org --fxaUntrustedOauthApp=https://321done-fxaci.dev.lcip.org --fxaProduction=true --bailAfterFirstFailure=true", "test-functional": "node tests/intern.js", "test-functional-oauth": "node tests/intern.js --grep='oauth'", "test-functional-settings": "node tests/intern.js --suites=settings", @@ -28,8 +32,6 @@ "test-pairing": "node tests/intern.js --suites=pairing", "test-pairing-circle": "node tests/intern.js --suites=pairing --fxaAuthRoot=https://fxaci.dev.lcip.org/auth --fxaEmailRoot=http://restmail.net --fxaOAuthApp=https://123done-fxaci.dev.lcip.org/ --fxaProduction=true --bailAfterFirstFailure=true", "test-server": "node tests/intern.js --suites=server", - "test-unit": "echo No unit tests present for $npm_package_name", - "test-integration": "echo No integration tests present for $npm_package_name", "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "repository": { @@ -191,5 +193,10 @@ "xmlhttprequest": "^1.8.0", "yargs": "^17.0.1" }, - "readmeFilename": "README.md" + "readmeFilename": "README.md", + "nx": { + "tags": [ + "scope:frontend" + ] + } } diff --git a/packages/fxa-content-server/pm2.config.js b/packages/fxa-content-server/pm2.config.js index 68029e322d..98ec71474e 100644 --- a/packages/fxa-content-server/pm2.config.js +++ b/packages/fxa-content-server/pm2.config.js @@ -7,52 +7,52 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); +const apps = []; + +apps.push({ + name: 'content', + script: 'node --inspect=9130 server/bin/fxa-content-server.js', + cwd: __dirname, + env: { + NODE_ENV: 'development', + NODE_OPTIONS: '--openssl-legacy-provider --dns-result-order=ipv4first', + CONFIG_FILES: 'server/config/local.json', + PORT: 3030, + PATH, + SENTRY_ENV: 'local', + SENTRY_DSN: process.env.SENTRY_DSN_CONTENT, + TRACING_SERVICE_NAME: 'fxa-content-server', + TRACING_CLIENT_NAME: 'fxa-content-client', + }, +}); + +if (process.env.CI !== 'true') { + apps.push({ + name: 'content-css', + script: 'yarn build-css', + cwd: __dirname, + env: { + PATH, + }, + filter_env: ['npm_'], + autorestart: false, + watch: [ + 'postcss.config.js', + 'tailwind.config.js', + 'app/scripts/templates/**/*.mustache', + 'app/styles/tailwind.css', + 'app/styles/tailwind/**/*.css', + require.resolve('fxa-react/configs/tailwind'), + path.normalize( + `${path.dirname( + require.resolve('fxa-react/configs/tailwind') + )}/../styles` + ), + ], + time: true, + }); +} + module.exports = { - apps: [ - { - name: 'content', - script: 'node --inspect=9130 server/bin/fxa-content-server.js', - cwd: __dirname, - env: { - NODE_ENV: 'development', - NODE_OPTIONS: '--openssl-legacy-provider --dns-result-order=ipv4first', - CONFIG_FILES: 'server/config/local.json', - PORT: 3030, - PATH, - SENTRY_ENV: 'local', - SENTRY_DSN: process.env.SENTRY_DSN_CONTENT, - TRACING_SERVICE_NAME: 'fxa-content-server', - TRACING_CLIENT_NAME: 'fxa-content-client', - }, - filter_env: ['npm_'], - watch: ['server'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - { - name: 'content-css', - script: 'yarn build-css', - cwd: __dirname, - env: { - PATH, - }, - filter_env: ['npm_'], - autorestart: false, - watch: [ - 'postcss.config.js', - 'tailwind.config.js', - 'app/scripts/templates/**/*.mustache', - 'app/styles/tailwind.css', - 'app/styles/tailwind/**/*.css', - require.resolve('fxa-react/configs/tailwind'), - path.normalize( - `${path.dirname( - require.resolve('fxa-react/configs/tailwind') - )}/../styles` - ), - ], - time: true, - }, - ], + apps, }; diff --git a/packages/fxa-content-server/scripts/start-services.sh b/packages/fxa-content-server/scripts/start-services.sh index fe6f1d4066..824d60b9e2 100755 --- a/packages/fxa-content-server/scripts/start-services.sh +++ b/packages/fxa-content-server/scripts/start-services.sh @@ -15,27 +15,17 @@ cd ../../ mkdir -p ~/.pm2/logs mkdir -p artifacts/tests -CI=true yarn workspaces foreach \ - --verbose \ - --topological-dev \ - --include 123done \ - --include browserid-verifier \ - --include fxa-auth-server \ - --include fxa-content-server \ - --include fxa-graphql-api \ - --include fxa-payments-server \ - --include fxa-profile-server \ - --include fxa-settings \ - run start > ~/.pm2/logs/startup.log - -# stop services that aren't needed. These are 'watching' services, and they just -# consume memory. Ideally, we wouldn't even start these, but they are baked into -# the pm2 config start up. -npx pm2 stop auth-ftl & -npx pm2 stop settings-css & -npx pm2 stop settings-ftl & -npx pm2 stop payments-css & -npx pm2 stop payments-ftl & -wait +CI=false NODE_ENV=test npx nx run-many \ + -t start \ + --parallel=3 \ + -p \ + 123done \ + browserid-verifier \ + fxa-auth-server \ + fxa-content-server \ + fxa-graphql-api \ + fxa-payments-server \ + fxa-profile-server \ + fxa-settings; npx pm2 ls diff --git a/packages/fxa-customs-server/package.json b/packages/fxa-customs-server/package.json index 7d0ef44b60..d4f8cb56aa 100644 --- a/packages/fxa-customs-server/package.json +++ b/packages/fxa-customs-server/package.json @@ -12,6 +12,7 @@ "homepage": "https://github.com/mozilla/fxa/tree/main/packages/fxa-customs-server", "bugs": "https://github.com/mozilla/fxa/issues/", "scripts": { + "clean": "rimraf dist", "outdated": "npm outdated --depth 0 || exit 0", "start": "pm2 start pm2.config.js", "stop": "pm2 stop pm2.config.js", @@ -65,5 +66,10 @@ "tap": "^16.3.0", "tap-xunit": "^2.4.1", "walk": "^2.3.15" + }, + "nx": { + "tags": [ + "scope:server" + ] } } diff --git a/packages/fxa-dev-launcher/package.json b/packages/fxa-dev-launcher/package.json index fda7af0b42..e64b390b50 100644 --- a/packages/fxa-dev-launcher/package.json +++ b/packages/fxa-dev-launcher/package.json @@ -4,7 +4,8 @@ "description": "", "scripts": { "lint": "eslint . --ext .mjs", - "start": "./bin/fxa-dev-launcher.mjs" + "start": "./bin/fxa-dev-launcher.mjs", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "bin": "./bin/fxa-dev-launcher.mjs", "repository": { diff --git a/packages/fxa-event-broker/package.json b/packages/fxa-event-broker/package.json index 746f46120e..d1af4a6ae3 100644 --- a/packages/fxa-event-broker/package.json +++ b/packages/fxa-event-broker/package.json @@ -8,7 +8,7 @@ "build": "nest build", "compile": "tsc --noEmit", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", - "start": "../../_scripts/check-url.sh localhost:9000/__heartbeat__ && pm2 start pm2.config.js", + "start": "yarn check:url localhost:9000/__heartbeat__ && pm2 start pm2.config.js", "start-prod": "node dist/packages/fxa-event-broker/src/main", "lint": "eslint {src,test}/**/*.ts", "test": "jest --runInBand", @@ -117,5 +117,10 @@ }, "coverageDirectory": "../coverage", "testEnvironment": "node" + }, + "nx": { + "tags": [ + "scope:broker" + ] } } diff --git a/packages/fxa-event-broker/scripts/test-ci.sh b/packages/fxa-event-broker/scripts/test-ci.sh index 27a4555a71..e3090092f9 100755 --- a/packages/fxa-event-broker/scripts/test-ci.sh +++ b/packages/fxa-event-broker/scripts/test-ci.sh @@ -1,3 +1,3 @@ #!/bin/bash -e -yarn test --runInBand +npx nx fxa-event-broker:test --runInBand diff --git a/packages/fxa-geodb/README.md b/packages/fxa-geodb/README.md index ebc69d8d00..0be4aeeee7 100644 --- a/packages/fxa-geodb/README.md +++ b/packages/fxa-geodb/README.md @@ -93,7 +93,7 @@ Refer to Mocha's [CLI documentation](https://mochajs.org/#command-line-usage) fo ### Code Coverage -Code coverage is provided with `nyc`, to run coverage, call `yarn-script cover` +Code coverage is provided with `nyc`, to run coverage, call `yarn cover` -- diff --git a/packages/fxa-geodb/package.json b/packages/fxa-geodb/package.json index 04393af0f2..a5291d6875 100644 --- a/packages/fxa-geodb/package.json +++ b/packages/fxa-geodb/package.json @@ -7,6 +7,7 @@ "test": "test" }, "scripts": { + "clean": "rimraf dist", "cover": "nyc _mocha", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", "lint": "eslint .", @@ -50,5 +51,10 @@ "mocha": { "reporter": "mocha-multi", "reporterOptions": "spec=-,mocha-junit-reporter=-" + }, + "nx": { + "tags": [ + "scope:shared:service" + ] } } diff --git a/packages/fxa-graphql-api/package.json b/packages/fxa-graphql-api/package.json index 9d37123968..32090210fb 100644 --- a/packages/fxa-graphql-api/package.json +++ b/packages/fxa-graphql-api/package.json @@ -3,14 +3,15 @@ "version": "0.0.0", "description": "FxA GraphQL API", "scripts": { - "prebuild": "rimraf dist && yarn gql:allowlist", - "copy-gql": "mkdir -p src/config/gql/allowlist/ && cp ../../configs/gql/allowlist/*.json src/config/gql/allowlist/.", - "build": "nest build", + "prebuild": "yarn clean", + "gql-copy": "mkdir -p src/config/gql/allowlist/ && cp ../../configs/gql/allowlist/*.json src/config/gql/allowlist/.", + "build": "yarn compile && nest build", + "clean": "rimraf dist", "compile": "tsc --noEmit", "lint": "eslint .", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", "watch": "tsc -w", - "start": "pm2 start pm2.config.js && ../../_scripts/check-url.sh localhost:8290/__heartbeat__", + "start": "pm2 start pm2.config.js && yarn check:url localhost:8290/__heartbeat__", "stop": "pm2 stop pm2.config.js", "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", @@ -20,8 +21,9 @@ "test-watch": "jest --watch", "test-cov": "jest --coverage", "test-debug": "node --inspect-brk -r tsconfig-paths/register -r esbuild-register node_modules/.bin/jest --runInBand --logHeapUsage", - "test-e2e": "npm run build && JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-e2e.xml jest --runInBand --logHeapUsage --config ./test/jest-e2e.config.js --ci --reporters=default --reporters=jest-junit", - "email-bounce": "node -r esbuild-register ./scripts/email-bounce.ts" + "test-e2e": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-e2e.xml jest --runInBand --logHeapUsage --config ./test/jest-e2e.config.js --ci --reporters=default --reporters=jest-junit", + "email-bounce": "node -r esbuild-register ./scripts/email-bounce.ts", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "repository": { "type": "git", diff --git a/packages/fxa-graphql-api/pm2.config.js b/packages/fxa-graphql-api/pm2.config.js index 1ec66f10bf..6a30f8fc04 100644 --- a/packages/fxa-graphql-api/pm2.config.js +++ b/packages/fxa-graphql-api/pm2.config.js @@ -8,8 +8,8 @@ const PATH = process.env.PATH.split(':') const nest = require.resolve('@nestjs/cli/bin/nest.js'); const getNestScript = () => `${nest} start`; -const getProdScript = () => - 'rm -rf dist && yarn build && node dist/packages/fxa-graphql-api/src/main.js'; +const getProdScript = () => 'node dist/packages/fxa-graphql-api/src/main.js'; + const script = process.env.CI === 'true' || process.env.NODE_ENV === 'production' ? getProdScript() diff --git a/packages/fxa-graphql-api/src/backend/legal.service.spec.ts b/packages/fxa-graphql-api/src/backend/legal.service.spec.ts index 2403f627ba..a203cb61d7 100644 --- a/packages/fxa-graphql-api/src/backend/legal.service.spec.ts +++ b/packages/fxa-graphql-api/src/backend/legal.service.spec.ts @@ -112,26 +112,26 @@ describe('#unit - LegalService', () => { }); describe('invalid files', () => { - async function test(fileName: string) { + async function testGetDoc(fileName: string) { await expect(async () => { await service.getDoc('en', fileName); }).rejects.toThrow('Invalid file name'); } it('rejects empty file name', async () => { - await test(''); + await testGetDoc(''); }); it('rejects relative path like file name', async () => { - await test('../foo.txt'); + await testGetDoc('../foo.txt'); }); it('rejects absolute path like file name', async () => { - await test('/foo/bar.txt'); + await testGetDoc('/foo/bar.txt'); }); it('rejects long file name', async () => { - await test('a'.repeat(1000)); + await testGetDoc('a'.repeat(1000)); }); }); }); diff --git a/packages/fxa-graphql-api/src/gql/gql.module.ts b/packages/fxa-graphql-api/src/gql/gql.module.ts index d400c95c72..77ab29d5ec 100644 --- a/packages/fxa-graphql-api/src/gql/gql.module.ts +++ b/packages/fxa-graphql-api/src/gql/gql.module.ts @@ -25,7 +25,6 @@ import Config, { AppConfig } from '../config'; import { AccountResolver } from './account.resolver'; import { SessionResolver } from './session.resolver'; import { LegalResolver } from './legal.resolver'; -import { CartResolver } from './cart.resolver'; import { Request, Response } from 'express'; const config = Config.getProperties(); diff --git a/packages/fxa-graphql-api/src/gql/lib/error.ts b/packages/fxa-graphql-api/src/gql/lib/error.ts index 7d52310a02..09dee06a9c 100644 --- a/packages/fxa-graphql-api/src/gql/lib/error.ts +++ b/packages/fxa-graphql-api/src/gql/lib/error.ts @@ -4,20 +4,7 @@ import { ApolloError } from 'apollo-server'; -export class ThrottledError extends ApolloError { - constructor( - message: string, - code: string, - extensions: { - errno: number; - info: string; - retryAfter: number; - retryAfterLocalized: string; - } - ) { - super(message, code, extensions); - } -} +export class ThrottledError extends ApolloError {} export const PROFILE_INFO_URL = 'https://github.com/mozilla/fxa/blob/main/packages/fxa-profile-server/docs/API.md#errors'; diff --git a/packages/fxa-payments-server/package.json b/packages/fxa-payments-server/package.json index c5fa57a81e..e63bc0799b 100644 --- a/packages/fxa-payments-server/package.json +++ b/packages/fxa-payments-server/package.json @@ -3,31 +3,35 @@ "version": "0.0.0", "description": "Firefox Accounts Payments Service", "scripts": { + "prebuild": "yarn l10n-prime", + "build": "yarn build-l10n && yarn build-css && yarn build-ts && yarn build-react", "build-css": "npx tailwindcss --postcss -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css", + "build-ts": "tsc", + "build-l10n": "nx l10n-merge && nx l10n-bundle && nx l10n-merge-test", + "build-react": "SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false CI=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", + "build-storybook": "NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/images storybook-static/ && cp -r public/locales ./storybook-static/locales", "compile": "tsc --noEmit", - "postinstall": "yarn l10n:prime fxa-payments-server", - "clean": "git clean -fXd", + "clean": "rimraf dist", + "l10n-merge": "yarn grunt merge-ftl", + "l10n-merge-test": "yarn grunt merge-ftl:test", "l10n-prime": "yarn l10n:prime fxa-payments-server", "l10n-bundle": "yarn l10n:bundle fxa-payments-server branding,react,payments", + "l10n-watch": "yarn grunt watch-ftl", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", - "start": "tsc --build ../fxa-react && yarn build-css && yarn merge-ftl && pm2 start pm2.config.js && ../../_scripts/check-url.sh localhost:3031/__lbheartbeat__", + "start": "pm2 start pm2.config.js && yarn check:url localhost:3031/__lbheartbeat__", "stop": "pm2 stop pm2.config.js", - "restart": "tsc --build ../fxa-react && yarn build-css && pm2 restart pm2.config.js", + "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", - "build": "yarn merge-ftl && tsc --build ../fxa-react && NODE_ENV=production yarn build-css && SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false CI=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", "eject": "react-scripts eject", "test": "yarn test-frontend && yarn test-server", - "test-frontend": "yarn merge-ftl-test && SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test --watchAll=false", - "test-frontend-watch": "yarn merge-ftl-test && SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test", - "test-server": "yarn merge-ftl-test && yarn build && jest --coverage --runInBand --logHeapUsage --verbose --config server/jest.config.js --forceExit", - "test-unit": "yarn build && yarn merge-ftl-test && JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-unit.xml jest --coverage --runInBand --logHeapUsage --verbose --config server/jest.config.js --forceExit -t '^(?!.*?#integration).*' --ci --reporters=default --reporters=jest-junit", - "test-integration": "yarn build && yarn merge-ftl-test && JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-integration.xml SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test --watchAll=false --ci --reporters=default --reporters=jest-junit", + "test-frontend": "SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test --watchAll=false", + "test-frontend-watch": "SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test", + "test-server": "jest --coverage --runInBand --logHeapUsage --verbose --config server/jest.config.js --forceExit", + "test-unit": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-unit.xml jest --coverage --runInBand --logHeapUsage --verbose --config server/jest.config.js --forceExit -t '^(?!.*?#integration).*' --ci --reporters=default --reporters=jest-junit", + "test-integration": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-integration.xml SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/ INLINE_RUNTIME_CHUNK=false rescripts test --watchAll=false --ci --reporters=default --reporters=jest-junit", "format": "prettier --write --config ../../_dev/.prettierrc '**'", - "storybook": "NODE_OPTIONS=--openssl-legacy-provider storybook dev -p 6006", - "build-storybook": "yarn merge-ftl && NODE_ENV=production yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/images storybook-static/ && cp -r public/locales ./storybook-static/locales", - "merge-ftl": "yarn l10n-prime && grunt merge-ftl && yarn l10n-bundle", - "merge-ftl-test": "yarn l10n-prime && grunt merge-ftl:test", - "watch-ftl": "grunt watch-ftl" + "storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006", + "watch-ftl": "yarn l10n-watch" }, "eslintConfig": { "extends": [ @@ -192,5 +196,10 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "nx": { + "tags": [ + "scope:frontend" + ] } } diff --git a/packages/fxa-payments-server/pm2.config.js b/packages/fxa-payments-server/pm2.config.js index 1732e7f639..ae23a5c1a1 100644 --- a/packages/fxa-payments-server/pm2.config.js +++ b/packages/fxa-payments-server/pm2.config.js @@ -7,80 +7,84 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); +const apps = []; +apps.push({ + name: 'payments', + cwd: __dirname, + script: 'node server/bin/fxa-payments-server.js', + max_restarts: '1', + min_uptime: '2m', + env: { + LOGGING_FORMAT: 'pretty', + NODE_ENV: 'development', + NODE_OPTIONS: '--inspect=9170 --dns-result-order=ipv4first', + PROXY_STATIC_RESOURCES_FROM: 'http://localhost:3032', + CONFIG_FILES: 'server/config/secrets.json', + PORT: '3031', + PATH, + SENTRY_ENV: 'local', + SENTRY_DSN: process.env.SENTRY_DSN_PAYMENTS, + TRACING_SERVICE_NAME: 'fxa-payments-server', + }, + filter_env: ['npm_'], + time: true, +}); +apps.push({ + name: 'payments-react', + cwd: __dirname, + script: 'yarn rescripts start', + max_restarts: '1', + min_uptime: '2m', + env: { + SKIP_PREFLIGHT_CHECK: 'true', + NODE_ENV: 'development', + NODE_OPTIONS: '--openssl-legacy-provider', + PUBLIC_URL: 'http://localhost:3031', + BROWSER: 'NONE', + PORT: '3032', + PATH, + }, + filter_env: ['npm_', 'BERRY_BIN_FOLDER'], + time: true, +}); + +if (process.env.CI !== 'true') { + apps.push({ + name: 'payments-css', + script: 'yarn build-css', + cwd: __dirname, + env: { + PATH, + }, + filter_env: ['npm_'], + autorestart: false, + watch: [ + 'postcss.config.js', + 'tailwind.config.js', + 'src/styles', + 'src/components/**/*.css', + 'src/**/*.tsx', + require.resolve('fxa-react/configs/tailwind'), + path.normalize( + `${path.dirname( + require.resolve('fxa-react/configs/tailwind') + )}/../styles` + ), + ], + ignore_watch: ['src/styles/tailwind.out.*'], + time: true, + }); + apps.push({ + name: 'payments-ftl', + script: 'yarn grunt watch-ftl', + cwd: __dirname, + filter_env: ['npm_'], + max_restarts: '1', + min_uptime: '2m', + time: true, + }); +} + module.exports = { - apps: [ - { - name: 'payments', - cwd: __dirname, - script: 'node server/bin/fxa-payments-server.js', - max_restarts: '1', - min_uptime: '2m', - env: { - LOGGING_FORMAT: 'pretty', - NODE_ENV: 'development', - NODE_OPTIONS: '--inspect=9170 --dns-result-order=ipv4first', - PROXY_STATIC_RESOURCES_FROM: 'http://localhost:3032', - CONFIG_FILES: 'server/config/secrets.json', - PORT: '3031', - PATH, - SENTRY_ENV: 'local', - SENTRY_DSN: process.env.SENTRY_DSN_PAYMENTS, - TRACING_SERVICE_NAME: 'fxa-payments-server', - }, - filter_env: ['npm_'], - time: true, - }, - { - name: 'payments-react', - cwd: __dirname, - script: 'yarn rescripts start', - max_restarts: '1', - min_uptime: '2m', - env: { - SKIP_PREFLIGHT_CHECK: 'true', - NODE_ENV: 'development', - NODE_OPTIONS: '--openssl-legacy-provider', - PUBLIC_URL: 'http://localhost:3031', - BROWSER: 'NONE', - PORT: '3032', - PATH, - }, - filter_env: ['npm_', 'BERRY_BIN_FOLDER'], - time: true, - }, - { - name: 'payments-css', - script: 'yarn build-css', - cwd: __dirname, - env: { - PATH, - }, - filter_env: ['npm_'], - autorestart: false, - watch: [ - 'postcss.config.js', - 'tailwind.config.js', - 'src/styles', - 'src/components/**/*.css', - 'src/**/*.tsx', - require.resolve('fxa-react/configs/tailwind'), - path.normalize( - `${path.dirname( - require.resolve('fxa-react/configs/tailwind') - )}/../styles` - ), - ], - ignore_watch: ['src/styles/tailwind.out.*'], - time: true, - }, - { - name: 'payments-ftl', - script: 'yarn grunt watch-ftl', - cwd: __dirname, - filter_env: ['npm_'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - ], + apps, }; diff --git a/packages/fxa-payments-server/scripts/test-ci.sh b/packages/fxa-payments-server/scripts/test-ci.sh index d6a8b19846..494d39dd52 100755 --- a/packages/fxa-payments-server/scripts/test-ci.sh +++ b/packages/fxa-payments-server/scripts/test-ci.sh @@ -1,4 +1,4 @@ #!/bin/bash -ex -yarn workspace fxa-payments-server build -NODE_ENV=test yarn workspace fxa-payments-server test +npx nx fxa-payments-server:build +NODE_ENV=test npx nx fxa-payments-server:test diff --git a/packages/fxa-profile-server/package.json b/packages/fxa-profile-server/package.json index 3dd56cd6d8..4bbbc6deb4 100644 --- a/packages/fxa-profile-server/package.json +++ b/packages/fxa-profile-server/package.json @@ -6,16 +6,18 @@ "scripts": { "lint": "eslint .", "audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-", + "clean": "rimraf dist", + "prebuild": "mkdir -p var/public", "outdated": "npm outdated --depth 0 || exit 0", - "start": "yarn make-dirs && pm2 start pm2.config.js && ../../_scripts/check-url.sh localhost:1111/__heartbeat__", + "build": "echo 'Build not required'", + "start": "pm2 start pm2.config.js && yarn check:url localhost:1111/__heartbeat__", "stop": "pm2 stop pm2.config.js", "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", "test": "scripts/test-local.sh", - "test-unit": "yarn make-dirs && MOCHA_FILE=../../artifacts/tests/$npm_package_name/mocha-unit.xml node ./scripts/mocha-coverage.js --recursive test/*.js test/routes/*/*.js -g '#integration' --invert", - "test-integration": "yarn make-dirs && MOCHA_FILE=../../artifacts/tests/$npm_package_name/mocha-integration.xml node ./scripts/mocha-coverage.js --recursive test/*.js test/routes/*/*.js -g '#integration'", - "format": "prettier --write --config ../../_dev/.prettierrc '**'", - "make-dirs": "mkdir -p var/public" + "test-unit": "MOCHA_FILE=../../artifacts/tests/$npm_package_name/mocha-unit.xml node ./scripts/mocha-coverage.js --recursive test/*.js test/routes/*/*.js -g '#integration' --invert", + "test-integration": "mkdir -p var/public && MOCHA_FILE=../../artifacts/tests/$npm_package_name/mocha-integration.xml node ./scripts/mocha-coverage.js --recursive test/*.js test/routes/*/*.js -g '#integration'", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "dependencies": { "@hapi/boom": "~10.0.0", @@ -70,5 +72,10 @@ "mocha": { "reporter": "mocha-multi", "reporterOptions": "spec=-,mocha-junit-reporter=-" + }, + "nx": { + "tags": [ + "scope:server" + ] } } diff --git a/packages/fxa-profile-server/scripts/test-ci.sh b/packages/fxa-profile-server/scripts/test-ci.sh index d7a88dc12a..547c5c338d 100755 --- a/packages/fxa-profile-server/scripts/test-ci.sh +++ b/packages/fxa-profile-server/scripts/test-ci.sh @@ -8,4 +8,4 @@ mkdir -p var/public # Copy version info cp "$DIR/../../version.json" "$DIR/../config" -NODE_ENV=test yarn test +NODE_ENV=test npx nx fxa-profile-server:test diff --git a/packages/fxa-react/package.json b/packages/fxa-react/package.json index 8d4bc46b2e..b2b7c6dd03 100644 --- a/packages/fxa-react/package.json +++ b/packages/fxa-react/package.json @@ -12,25 +12,28 @@ "./lib/": "./lib/" }, "scripts": { + "prebuild": "nx l10n-prime", + "build": "nx build-l10n && nx build-css && nx build-ts", "build-css": "npx tailwindcss -i ./styles/tailwind.css -o ./styles/tailwind.out.css", - "build-storybook": "yarn merge-ftl && NODE_ENV=production yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/locales ./storybook-static/locales", - "build": "tsc --build && yarn merge-ftl", - "compile": "tsc --noEmit", - "clean": "git clean -fXd", + "build-ts": "tsc --build", + "build-storybook": "NODE_ENV=production yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/locales ./storybook-static/locales", + "build-l10n": "nx l10n-merge && nx l10n-merge-test", + "compile": "nx build-ts", + "clean": "rimraf dist", "l10n-prime": "yarn l10n:prime fxa-react", + "l10n-merge": "yarn grunt merge-ftl", + "l10n-merge-test": "yarn grunt merge-ftl:test", + "l10n-watch": "yarn grunt watch-ftl", "lint": "eslint . .storybook", "format": "prettier --write --config ../../_dev/.prettierrc '**'", "restart": "pm2 restart pm2.config.js", - "start": "yarn merge-ftl && pm2 start pm2.config.js", + "start": "pm2 start pm2.config.js", "stop": "pm2 stop pm2.config.js", "delete": "pm2 delete pm2.config.js", - "storybook": "yarn merge-ftl && yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook dev -p 6007 --no-version-updates", - "test": "yarn merge-ftl-test && JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-unit.xml jest --coverage --runInBand --logHeapUsage --env=jest-environment-jsdom -t '^(?!.*?#integration).*' --ci --reporters=default --reporters=jest-junit ", - "test-unit": "yarn test", - "test-integration": "echo No integration tests present for $npm_package_name", - "merge-ftl": "yarn l10n-prime && grunt merge-ftl", - "merge-ftl-test": "yarn l10n-prime && grunt merge-ftl:test", - "watch-ftl": "grunt watch-ftl" + "storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6007 --no-version-updates", + "test": "yarn test-unit && yarn test-integration", + "test-unit": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-unit.xml jest --coverage --runInBand --logHeapUsage --env=jest-environment-jsdom -t '^(?!.*?#integration).*' --ci --reporters=default --reporters=jest-junit", + "watch-ftl": "yarn l10n-watch" }, "dependencies": { "@fluent/bundle": "^0.18.0", @@ -104,5 +107,10 @@ "license": "MPL-2.0", "bugs": { "url": "https://github.com/mozilla/fxa/issues" + }, + "nx": { + "tags": [ + "scope:shared:lib" + ] } } diff --git a/packages/fxa-react/pm2.config.js b/packages/fxa-react/pm2.config.js index 89db37a68e..3b3944ef5f 100644 --- a/packages/fxa-react/pm2.config.js +++ b/packages/fxa-react/pm2.config.js @@ -6,8 +6,10 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); -module.exports = { - apps: [ +let apps = []; + +if (process.env.CI !== 'true') { + apps = [ { name: 'react-tsc', script: 'yarn tsc --build --watch', @@ -38,5 +40,9 @@ module.exports = { ignore_watch: ['styles/tailwind.out.css'], time: true, }, - ], + ]; +} + +module.exports = { + apps, }; diff --git a/packages/fxa-react/scripts/test-ci.sh b/packages/fxa-react/scripts/test-ci.sh index a81ecb29a7..fa26296986 100755 --- a/packages/fxa-react/scripts/test-ci.sh +++ b/packages/fxa-react/scripts/test-ci.sh @@ -1,4 +1,3 @@ #!/bin/bash -ex -yarn workspaces focus fxa-react -CI=yes NODE_ENV=test yarn test +CI=yes NODE_ENV=test npx nx fxa-react:test diff --git a/packages/fxa-settings/.eslintignore b/packages/fxa-settings/.eslintignore new file mode 100644 index 0000000000..20687473be --- /dev/null +++ b/packages/fxa-settings/.eslintignore @@ -0,0 +1 @@ +storybook-static diff --git a/packages/fxa-settings/.storybook/design-guide/pages/Breakpoints.tsx b/packages/fxa-settings/.storybook/design-guide/pages/Breakpoints.tsx index 54075208b6..021472fb71 100644 --- a/packages/fxa-settings/.storybook/design-guide/pages/Breakpoints.tsx +++ b/packages/fxa-settings/.storybook/design-guide/pages/Breakpoints.tsx @@ -130,4 +130,5 @@ const Breakpoints = ({ config }) => { ); }; -export default (config) => Breakpoints(config); +const breakpoints = (config) => Breakpoints(config); +export default breakpoints; diff --git a/packages/fxa-settings/.storybook/design-guide/pages/Colors.tsx b/packages/fxa-settings/.storybook/design-guide/pages/Colors.tsx index ac51193b81..721535fb47 100644 --- a/packages/fxa-settings/.storybook/design-guide/pages/Colors.tsx +++ b/packages/fxa-settings/.storybook/design-guide/pages/Colors.tsx @@ -130,4 +130,5 @@ const Colors = ({ config }) => { ); }; -export default (config) => Colors(config); +const colors = (config) => Colors(config); +export default colors; diff --git a/packages/fxa-settings/.storybook/design-guide/pages/Introduction.tsx b/packages/fxa-settings/.storybook/design-guide/pages/Introduction.tsx index e2eff3067b..bf028a361f 100644 --- a/packages/fxa-settings/.storybook/design-guide/pages/Introduction.tsx +++ b/packages/fxa-settings/.storybook/design-guide/pages/Introduction.tsx @@ -82,4 +82,5 @@ export const Introduction = () => ( ); -export default () => Introduction(); +export const introduction = () => Introduction(); +export default introduction; diff --git a/packages/fxa-settings/.storybook/design-guide/pages/Spacing.tsx b/packages/fxa-settings/.storybook/design-guide/pages/Spacing.tsx index 7a9902dba5..2d5f19864f 100644 --- a/packages/fxa-settings/.storybook/design-guide/pages/Spacing.tsx +++ b/packages/fxa-settings/.storybook/design-guide/pages/Spacing.tsx @@ -2,8 +2,6 @@ import React from 'react'; import Page from '../Page'; import Copiable from '../Copiable'; import Snippet from '../Snippet'; -import { withLocalization } from 'fxa-react/lib/storybooks'; -import AppLocalizationProvider from 'fxa-react/lib/AppLocalizationProvider'; const nonIntMap = { px: { @@ -211,4 +209,5 @@ const Spacing = ({ config }) => { ); }; -export default (config) => Spacing(config); +const spacing = (config) => Spacing(config); +export default spacing; diff --git a/packages/fxa-settings/.storybook/design-guide/pages/Typography.tsx b/packages/fxa-settings/.storybook/design-guide/pages/Typography.tsx index 27daf51f6d..9f6979e10b 100644 --- a/packages/fxa-settings/.storybook/design-guide/pages/Typography.tsx +++ b/packages/fxa-settings/.storybook/design-guide/pages/Typography.tsx @@ -126,4 +126,5 @@ export const Typography = ({ config }) => { ); }; -export default (config) => Typography(config); +const typography = (config) => Typography(config); +export default typography; diff --git a/packages/fxa-settings/package.json b/packages/fxa-settings/package.json index 458c1c82bf..77a85411aa 100644 --- a/packages/fxa-settings/package.json +++ b/packages/fxa-settings/package.json @@ -4,30 +4,35 @@ "homepage": "https://accounts.firefox.com/settings", "private": true, "scripts": { - "build-css": "npx tailwindcss -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css --postcss", - "build-storybook": "yarn merge-ftl && NODE_ENV=production STORYBOOK_BUILD=1 yarn build-css && yarn legal-clone && LOG_LEVEL=TRACE NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/locales ./storybook-static/locales", - "extract-gql": "persistgraphql src ../../configs/gql/allowlist/fxa-settings.json --js --extension=ts ", - "build": "tsc --build ../fxa-react && NODE_ENV=production yarn build-css && yarn legal-clone && yarn merge-ftl && SKIP_PREFLIGHT_CHECK=true INLINE_RUNTIME_CHUNK=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", + "prebuild": "nx l10n-prime && nx legal-prime", + "build": "nx build-l10n && nx build-ts && nx build-css && nx build-react", + "build-ts": "tsc --build", + "build-css": "NODE_ENV=production tailwindcss -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css --postcss", + "build-storybook": "NODE_ENV=production STORYBOOK_BUILD=1 yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook build && cp -r public/locales ./storybook-static/locales", + "build-l10n": "nx l10n-merge && nx l10n-bundle && nx l10n-merge-test", + "build-react": "SKIP_PREFLIGHT_CHECK=true INLINE_RUNTIME_CHUNK=false NODE_OPTIONS=--openssl-legacy-provider rescripts build", + "clean": "rimraf dist", "compile": "tsc --noEmit", - "clean": "git clean -fXd", "eject": "react-scripts eject", - "l10n-prime": "yarn l10n:prime fxa-settings", + "gql-extract": "persistgraphql src ../../configs/gql/allowlist/fxa-settings.json --js --extension=ts ", "l10n-bundle": "yarn l10n:bundle fxa-settings branding,react,settings", - "legal-clone": "yarn legal:clone fxa-settings", + "l10n-prime": "yarn l10n:prime fxa-settings", + "l10n-merge": "yarn grunt merge-ftl", + "l10n-merge-test": "yarn grunt merge-ftl:test", + "legal-prime": "yarn legal:clone fxa-settings", "lint": "eslint . .storybook", - "restart": "yarn build-css && pm2 restart pm2.config.js", - "start": "yarn merge-ftl && yarn build-css && pm2 start pm2.config.js && ../../_scripts/check-url.sh localhost:3000/settings/static/js/bundle.js", + "start": "pm2 start pm2.config.js && yarn check:url localhost:3000/settings/static/js/bundle.js", "stop": "pm2 stop pm2.config.js", + "restart": "pm2 restart pm2.config.js", "delete": "pm2 delete pm2.config.js", - "storybook": "yarn legal-clone && STORYBOOK_BUILD=1 yarn build-css && NODE_OPTIONS=--openssl-legacy-provider storybook dev -p 6008 --no-version-updates", - "test": "yarn legal-clone && yarn merge-ftl-test && SKIP_PREFLIGHT_CHECK=true rescripts test --watchAll=false", - "test-watch": "yarn legal-clone && yarn merge-ftl-test && SKIP_PREFLIGHT_CHECK=true rescripts test", - "test-coverage": "yarn legal-clone && yarn test --coverage --watchAll=false", + "storybook": "STORYBOOK_BUILD=1 yarn build-css && NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6008 --no-version-updates", + "test": "SKIP_PREFLIGHT_CHECK=true rescripts test", + "test-watch": "SKIP_PREFLIGHT_CHECK=true rescripts test", + "test-coverage": "yarn test --coverage --watchAll=false", "test-unit": "echo No unit tests present for $npm_package_name", - "test-integration": "yarn legal-clone && yarn merge-ftl-test && tsc --build ../fxa-react && JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-integration.xml SKIP_PREFLIGHT_CHECK=true rescripts test --watchAll=false --ci --runInBand --reporters=default --reporters=jest-junit", - "merge-ftl": "yarn l10n-prime && grunt merge-ftl && yarn l10n-bundle", - "merge-ftl-test": "yarn l10n-prime && grunt merge-ftl:test", - "watch-ftl": "grunt watch-ftl" + "test-integration": "JEST_JUNIT_OUTPUT_FILE=../../artifacts/tests/$npm_package_name/jest-integration.xml SKIP_PREFLIGHT_CHECK=true rescripts test --watchAll=false --ci --runInBand --reporters=default --reporters=jest-junit", + "watch-ftl": "grunt watch-ftl", + "format": "prettier --write --config ../../_dev/.prettierrc '**'" }, "jest": { "resetMocks": false, @@ -156,5 +161,10 @@ "storybook-addon-rtl": "^0.5.0", "style-loader": "^1.3.0", "webpack": "^5.84.1" + }, + "nx": { + "tags": [ + "scope:frontend" + ] } } diff --git a/packages/fxa-settings/pm2.config.js b/packages/fxa-settings/pm2.config.js index 88ccf27687..6b16e1bf45 100644 --- a/packages/fxa-settings/pm2.config.js +++ b/packages/fxa-settings/pm2.config.js @@ -7,69 +7,67 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); +const apps = []; + +apps.push({ + name: 'settings-react', + cwd: __dirname, + script: 'yarn rescripts start', + max_restarts: '1', + min_uptime: '2m', + env: { + SKIP_PREFLIGHT_CHECK: 'true', + NODE_ENV: 'development', + NODE_OPTIONS: '--openssl-legacy-provider --dns-result-order=ipv4first', + BROWSER: 'NONE', + PORT: '3000', + PATH, + TRACING_SERVICE_NAME: 'fxa-settings-server', + TRACING_CLIENT_NAME: 'fxa-settings-client', + }, + filter_env: ['npm_', 'BERRY_BIN_FOLDER'], + time: true, +}); + +if (process.env.CI !== 'true') { + apps.push({ + name: 'settings-css', + script: 'yarn build-css', + cwd: __dirname, + env: { + PATH, + SENTRY_ENV: 'local', + SENTRY_DSN: process.env.SENTRY_DSN_CONTENT, // NOTE: Shared with content server intentionally + }, + filter_env: ['npm_'], + autorestart: false, + watch: [ + 'postcss.config.js', + 'tailwind.config.js', + 'src/styles', + 'src/**/*.tsx', + path.normalize( + `${path.dirname( + require.resolve('fxa-react/configs/tailwind') + )}/../styles` + ), + require.resolve('fxa-react/configs/tailwind'), + ], + ignore_watch: ['src/styles/tailwind.out.*'], + time: true, + }); + + apps.push({ + name: 'settings-ftl', + script: 'yarn grunt watch-ftl', + cwd: __dirname, + filter_env: ['npm_'], + max_restarts: '1', + min_uptime: '2m', + time: true, + }); +} + module.exports = { - apps: [ - { - name: 'settings-react', - cwd: __dirname, - script: 'yarn rescripts start', - max_restarts: '1', - min_uptime: '2m', - env: { - SKIP_PREFLIGHT_CHECK: 'true', - NODE_ENV: 'development', - NODE_OPTIONS: '--openssl-legacy-provider --dns-result-order=ipv4first', - BROWSER: 'NONE', - PORT: '3000', - PATH, - TRACING_SERVICE_NAME: 'fxa-settings-server', - TRACING_CLIENT_NAME: 'fxa-settings-client', - }, - filter_env: ['npm_', 'BERRY_BIN_FOLDER'], - time: true, - }, - { - name: 'settings-css', - script: 'yarn build-css', - cwd: __dirname, - env: { - PATH, - SENTRY_ENV: 'local', - SENTRY_DSN: process.env.SENTRY_DSN_CONTENT, // NOTE: Shared with content server intentionally - }, - filter_env: ['npm_'], - autorestart: false, - watch: [ - 'postcss.config.js', - 'tailwind.config.js', - 'src/styles', - 'src/**/*.tsx', - path.normalize( - `${path.dirname( - require.resolve('fxa-react/configs/tailwind') - )}/../styles` - ), - require.resolve('fxa-react/configs/tailwind'), - ], - ignore_watch: ['src/styles/tailwind.out.*'], - time: true, - }, - { - name: 'settings-ftl', - script: 'yarn grunt watch-ftl', - cwd: __dirname, - filter_env: ['npm_'], - max_restarts: '1', - min_uptime: '2m', - time: true, - }, - { - filter_env: ['npm_'], - autorestart: false, - name: 'settings-gql-allowlist', - script: 'yarn gql:allowlist', - cwd: __dirname, - watch: ['src/**/*.ts'], - }, - ], + apps, }; diff --git a/packages/fxa-settings/src/components/FormPassword/index.test.tsx b/packages/fxa-settings/src/components/FormPassword/index.test.tsx index 43b0feb99f..c3e3fb8a71 100644 --- a/packages/fxa-settings/src/components/FormPassword/index.test.tsx +++ b/packages/fxa-settings/src/components/FormPassword/index.test.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { typeByTestIdFn } from '../../lib/test-utils'; -import { screen, render } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider'; import { Subject } from './mocks'; diff --git a/packages/fxa-settings/src/components/GetDataTrio/index.stories.tsx b/packages/fxa-settings/src/components/GetDataTrio/index.stories.tsx index f527eb6f75..e8f16d378e 100644 --- a/packages/fxa-settings/src/components/GetDataTrio/index.stories.tsx +++ b/packages/fxa-settings/src/components/GetDataTrio/index.stories.tsx @@ -17,7 +17,7 @@ export default { } as Meta; export const Default = () => { - const [tooltipVisible, setTooltipVisible] = useState(false); + const [, setTooltipVisible] = useState(false); return (
@@ -26,7 +26,7 @@ export const Default = () => { }; export const SingleCopyButton = () => { - const [tooltipVisible, setTooltipVisible] = useState(false); + const [, setTooltipVisible] = useState(false); return (
@@ -35,7 +35,7 @@ export const SingleCopyButton = () => { }; export const SingleCopyButtonInline = () => { - const [tooltipVisible, setTooltipVisible] = useState(false); + const [, setTooltipVisible] = useState(false); return (
{ - const [formattedRecoveryKey, setFormattedRecoveryKey] = useState(''); + const [, setFormattedRecoveryKey] = useState(''); const ftlMsgResolver = useFtlMsgResolver(); const localizedBackButtonTitle = ftlMsgResolver.getMsg( diff --git a/packages/fxa-settings/src/components/Settings/Modal/index.tsx b/packages/fxa-settings/src/components/Settings/Modal/index.tsx index 8a2f0e9387..138028c99c 100644 --- a/packages/fxa-settings/src/components/Settings/Modal/index.tsx +++ b/packages/fxa-settings/src/components/Settings/Modal/index.tsx @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { ReactNode, useState } from 'react'; +import React, { ReactNode } from 'react'; import { useClickOutsideEffect } from 'fxa-react/lib/hooks'; import { useEscKeydownEffect, useChangeFocusEffect } from '../../../lib/hooks'; import classNames from 'classnames'; diff --git a/packages/fxa-settings/src/components/Settings/PageDeleteAccount/index.tsx b/packages/fxa-settings/src/components/Settings/PageDeleteAccount/index.tsx index 8fea19032a..9bf75615be 100644 --- a/packages/fxa-settings/src/components/Settings/PageDeleteAccount/index.tsx +++ b/packages/fxa-settings/src/components/Settings/PageDeleteAccount/index.tsx @@ -117,12 +117,12 @@ export const PageDeleteAccount = (_: RouteComponentProps) => { const goHome = useCallback(() => window.history.back(), []); const account = useAccount(); - + useEffect(() => { if (!account.hasPassword) { setSubtitleText(''); } - }, [account.hasPassword]); + }, [account.hasPassword]); const advanceStep = () => { // Accounts that do not have a password set, will delete immediately @@ -225,7 +225,8 @@ export const PageDeleteAccount = (_: RouteComponentProps) => { >

If you subscribe to Pocket Premium, please make sure that you{' '} - cancel your subscription before deleting your account. + cancel your subscription{' '} + before deleting your account.

diff --git a/packages/fxa-settings/src/models/integrations/oauth-integration.test.ts b/packages/fxa-settings/src/models/integrations/oauth-integration.test.ts index fac1cbf4a2..3ffb1ab848 100644 --- a/packages/fxa-settings/src/models/integrations/oauth-integration.test.ts +++ b/packages/fxa-settings/src/models/integrations/oauth-integration.test.ts @@ -67,7 +67,7 @@ describe('models/integrations/oauth-relier', function () { it('empty scope', async () => { await expect(async () => { const integration = getIntegration(''); - const _permissions = await integration.getPermissions(); + await integration.getPermissions(); }).rejects.toThrow(); }); diff --git a/packages/fxa-settings/src/models/integrations/oauth-integration.ts b/packages/fxa-settings/src/models/integrations/oauth-integration.ts index a069fadb53..c86488bd1c 100644 --- a/packages/fxa-settings/src/models/integrations/oauth-integration.ts +++ b/packages/fxa-settings/src/models/integrations/oauth-integration.ts @@ -27,8 +27,6 @@ import { MinLength, } from 'class-validator'; -const PKCE_CODE_CHALLENGE_LENGTH = 43; - interface OAuthIntegrationFeatures extends IntegrationFeatures { webChannelSupport: boolean; } diff --git a/packages/fxa-settings/src/models/integrations/sync-basic-integration.ts b/packages/fxa-settings/src/models/integrations/sync-basic-integration.ts index 905b330b9d..27f4d4090a 100644 --- a/packages/fxa-settings/src/models/integrations/sync-basic-integration.ts +++ b/packages/fxa-settings/src/models/integrations/sync-basic-integration.ts @@ -12,7 +12,6 @@ import { Constants } from '../../lib/constants'; import { BaseIntegrationData } from './web-integration'; import { IsBase64, - IsISO31661Alpha3, IsIn, IsOptional, IsString, diff --git a/packages/fxa-settings/src/models/verification/verification-info.ts b/packages/fxa-settings/src/models/verification/verification-info.ts index c2c9f05b98..5e06381ba0 100644 --- a/packages/fxa-settings/src/models/verification/verification-info.ts +++ b/packages/fxa-settings/src/models/verification/verification-info.ts @@ -2,14 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { - IsEmail, - IsHexadecimal, - IsNotEmpty, - IsOptional, - IsString, - Length, -} from 'class-validator'; +import { IsEmail, IsHexadecimal, IsOptional, Length } from 'class-validator'; import { ModelDataProvider, bind } from '../../lib/model-data'; export * from './verification-info'; diff --git a/packages/fxa-settings/src/pages/CannotCreateAccount/index.test.tsx b/packages/fxa-settings/src/pages/CannotCreateAccount/index.test.tsx index 6ce5a68735..7ee80d8e83 100644 --- a/packages/fxa-settings/src/pages/CannotCreateAccount/index.test.tsx +++ b/packages/fxa-settings/src/pages/CannotCreateAccount/index.test.tsx @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import React from 'react'; -import { screen, render } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider'; import { usePageViewEvent } from '../../lib/metrics'; import CannotCreateAccount, { viewName } from '.'; diff --git a/packages/fxa-settings/src/pages/Clear/index.test.tsx b/packages/fxa-settings/src/pages/Clear/index.test.tsx index 772f2ad7d3..4993979e5d 100644 --- a/packages/fxa-settings/src/pages/Clear/index.test.tsx +++ b/packages/fxa-settings/src/pages/Clear/index.test.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Clear from '.'; -import { screen, render } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider'; describe('Clear', () => { it('clears localStorage, sessionStorage, and sets cookie', () => { diff --git a/packages/fxa-settings/src/pages/Legal/index.test.tsx b/packages/fxa-settings/src/pages/Legal/index.test.tsx index 0773f11bdc..d8ce09ec9f 100644 --- a/packages/fxa-settings/src/pages/Legal/index.test.tsx +++ b/packages/fxa-settings/src/pages/Legal/index.test.tsx @@ -4,7 +4,7 @@ import React from 'react'; import Legal, { viewName } from '.'; -import { screen, render } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider'; import { usePageViewEvent } from '../../lib/metrics'; import { FluentBundle } from '@fluent/bundle'; diff --git a/packages/fxa-settings/src/pages/ResetPassword/index.tsx b/packages/fxa-settings/src/pages/ResetPassword/index.tsx index d631ad6ef0..ec937a6070 100644 --- a/packages/fxa-settings/src/pages/ResetPassword/index.tsx +++ b/packages/fxa-settings/src/pages/ResetPassword/index.tsx @@ -6,12 +6,7 @@ import { RouteComponentProps, useNavigate } from '@reach/router'; import React, { useCallback, useEffect, useState } from 'react'; import { Control, useForm, useWatch } from 'react-hook-form'; import { REACT_ENTRYPOINT } from '../../constants'; -import { - AuthUiErrorNos, - AuthUiErrors, - composeAuthUiErrorTranslationId, - getLocalizedErrorMessage, -} from '../../lib/auth-errors/auth-errors'; +import { getLocalizedErrorMessage } from '../../lib/auth-errors/auth-errors'; import { usePageViewEvent, useMetrics } from '../../lib/metrics'; import { MozServices } from '../../lib/types'; import { @@ -29,7 +24,6 @@ import { InputText } from '../../components/InputText'; import LinkRememberPassword from '../../components/LinkRememberPassword'; import WarningMessage from '../../components/WarningMessage'; import { isEmailValid } from 'fxa-shared/email/helpers'; -import sentryMetrics from 'fxa-shared/lib/sentry'; import { setOriginalTabMarker } from '../../lib/storage-utils'; import { ResetPasswordFormData, ResetPasswordProps } from './interfaces'; import { ConfirmResetPasswordLocationState } from './ConfirmResetPassword/interfaces'; diff --git a/packages/fxa-shared/package.json b/packages/fxa-shared/package.json index 5b9aad3738..cf402c4869 100644 --- a/packages/fxa-shared/package.json +++ b/packages/fxa-shared/package.json @@ -203,11 +203,12 @@ } }, "scripts": { - "postinstall": "yarn build || true", - "build": "tsc --build && tsc --build tsconfig.cjs.json && echo '{ \"type\": \"module\" }' > ./dist/esm/packages/fxa-shared/db/package.json && yarn copy-assets && yarn copy-sql", - "compile": "tsc --noEmit && yarn copy-assets && yarn copy-sql", + "build": "yarn build-ts && yarn copy-assets && yarn copy-sql", + "build-ts": "tsc --build && tsc --build tsconfig.cjs.json", + "clean": "rm -rf dist", + "compile": "yarn build-ts", "copy-assets": "cp -r ./db/luaScripts ./dist/esm/packages/fxa-shared/db/luaScripts; cp -r ./db/luaScripts ./dist/cjs/packages/fxa-shared/db/luaScripts", - "copy-sql": "find test -name \\*.sql -exec cp \\{\\} dist/esm/packages/fxa-shared/\\{\\} \\; ; find test -name \\*.sql -exec cp \\{\\} dist/cjs/packages/fxa-shared/\\{\\} \\;", + "copy-sql": "echo '{ \"type\": \"module\" }' > ./dist/esm/packages/fxa-shared/db/package.json && find test -name \\*.sql -exec cp \\{\\} dist/esm/packages/fxa-shared/\\{\\} \\; ; find test -name \\*.sql -exec cp \\{\\} dist/cjs/packages/fxa-shared/\\{\\} \\;", "start": "pm2 start pm2.config.js", "stop": "pm2 stop pm2.config.js", "restart": "pm2 restart pm2.config.js", @@ -365,5 +366,10 @@ "mocha": { "reporter": "mocha-multi", "reporterOptions": "spec=-,mocha-junit-reporter=-" + }, + "nx": { + "tags": [ + "scope:shared:lib" + ] } } diff --git a/packages/fxa-shared/pm2.config.js b/packages/fxa-shared/pm2.config.js index 80096b6bb6..259cf69dba 100644 --- a/packages/fxa-shared/pm2.config.js +++ b/packages/fxa-shared/pm2.config.js @@ -6,18 +6,22 @@ const PATH = process.env.PATH.split(':') .filter((p) => !p.includes(process.env.TMPDIR)) .join(':'); -module.exports = { - apps: [ - { - name: 'shared-tsc', - script: 'yarn tsc --build --watch', - cwd: __dirname, - max_restarts: '1', - env: { - PATH, - }, - filter_env: ['npm_'], - time: true, +const apps = []; + +if (process.env.CI !== 'true') { + apps.push({ + name: 'shared-tsc', + script: 'yarn tsc --build --watch', + cwd: __dirname, + max_restarts: '1', + env: { + PATH, }, - ], + filter_env: ['npm_'], + time: true, + }); +} + +module.exports = { + apps, };