.with-fixtures-needs: needs: - "rspec-all frontend_fixture" .with-graphql-schema-dump-needs: needs: - "graphql-schema-dump" .compile-assets-base: extends: - .default-retry - .default-before_script - .assets-compile-cache image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/${BUILD_OS}-${OS_VERSION}-ruby-${RUBY_VERSION}-node-${NODE_VERSION}:rubygems-${RUBYGEMS_VERSION}-git-2.33-lfs-2.9-yarn-1.22-graphicsmagick-1.3.36 variables: SETUP_DB: "false" WEBPACK_VENDOR_DLL: "true" # Disable warnings in browserslist which can break on backports # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 BROWSERSLIST_IGNORE_OLD_DATA: "true" WEBPACK_COMPILE_LOG_PATH: "tmp/webpack-output.log" stage: prepare needs: [] script: - yarn_install_script - export GITLAB_ASSETS_HASH=$(bin/rake gitlab:assets:hash_sum) - 'echo "CACHE_ASSETS_AS_PACKAGE: ${CACHE_ASSETS_AS_PACKAGE}"' # The new strategy to cache assets as generic packages is experimental and can be disabled by removing the `CACHE_ASSETS_AS_PACKAGE` variable - | if [[ "${CACHE_ASSETS_AS_PACKAGE}" == "true" ]]; then source scripts/gitlab_component_helpers.sh if ! gitlab_assets_archive_doesnt_exist; then # We remove all assets from the native cache as they could pollute the fresh assets from the package rm -rf public/assets/ app/assets/javascripts/locale/**/app.js run_timed_command "download_and_extract_gitlab_assets" fi fi - assets_compile_script - echo -n "${GITLAB_ASSETS_HASH}" > "cached-assets-hash.txt" .update-cache-base: after_script: - yarn patch-package --reverse # To avoid caching patched modules compile-production-assets: extends: - .compile-assets-base - .production - .frontend:rules:compile-production-assets artifacts: name: webpack-report expire_in: 31d paths: # These assets are used in multiple locations: # - in `build-assets-image` job to create assets image for packaging systems # - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1 - cached-assets-hash.txt - public/assets/ - "${WEBPACK_COMPILE_LOG_PATH}" when: always compile-production-assets as-if-foss: extends: - compile-production-assets - .as-if-foss - .frontend:rules:compile-production-assets-as-if-foss follow-up:compile-production-assets: extends: - compile-production-assets - .qa:rules:follow-up-e2e needs: - manual:e2e-test-pipeline-generate compile-test-assets: extends: - .compile-assets-base - .frontend:rules:compile-test-assets artifacts: expire_in: 7d paths: - public/assets/ - config/helpers/tailwind/ # Assets created during tailwind compilation - "${WEBPACK_COMPILE_LOG_PATH}" when: always update-assets-compile-production-cache: extends: - compile-production-assets - .update-cache-base - .assets-compile-cache-push - .shared:rules:update-cache artifacts: {} # This job's purpose is only to update the cache. update-assets-compile-test-cache: extends: - compile-test-assets - .update-cache-base - .assets-compile-cache-push - .shared:rules:update-cache artifacts: {} # This job's purpose is only to update the cache. update-storybook-yarn-cache: extends: - .default-retry - .default-utils-before_script - .update-cache-base - .storybook-yarn-cache-push - .shared:rules:update-cache stage: prepare script: - yarn_install_script_storybook retrieve-frontend-fixtures: variables: SETUP_DB: "false" extends: - .default-retry - .frontend:rules:default-frontend-jobs stage: prepare needs: [] script: - source scripts/utils.sh - source scripts/gitlab_component_helpers.sh - install_gitlab_gem - export_fixtures_sha_for_download - | if check_fixtures_download; then run_timed_command "download_and_extract_fixtures" fi artifacts: expire_in: 30 days paths: - tmp/tests/frontend/ # Download fixtures only when a merge request contains changes to only JS files # and fixtures are present in the package registry. .frontend-fixtures-base: extends: - .default-retry - .default-before_script - .ruby-cache - .use-pg14 - .repo-from-artifacts stage: fixtures needs: - "setup-test-env" - "retrieve-tests-metadata" - "retrieve-frontend-fixtures" # it's ok to wait for the repo artifact as we're waiting for setup-test-env (which takes longer than clone-gitlab-repo) anyway - !reference [.repo-from-artifacts, needs] variables: # Don't add `CRYSTALBALL: "false"` here as we're enabling Crystalball for scheduled pipelines (in `.gitlab-ci.yml`), so that we get coverage data # for the `frontend fixture RSpec files` that will be added to the Crystalball mapping in `update-tests-metadata`. # More information in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74003. WEBPACK_VENDOR_DLL: "true" script: - source scripts/gitlab_component_helpers.sh - | if check_fixtures_reuse; then echoinfo "INFO: Reusing frontend fixtures from 'retrieve-frontend-fixtures'." exit 0 fi - run_timed_command "gem install knapsack --no-document" - section_start "gitaly-test-spawn" "Spawning Gitaly"; scripts/gitaly-test-spawn; section_end "gitaly-test-spawn"; # Do not use 'bundle exec' here - source ./scripts/rspec_helpers.sh - rspec_parallelized_job artifacts: name: frontend-fixtures expire_in: 31d when: always paths: - crystalball/ - knapsack/ - log/*.log - tmp/tests/frontend/ # Builds FOSS, and EE fixtures in the EE project. # Builds FOSS fixtures in the FOSS project. rspec-all frontend_fixture: extends: - .frontend-fixtures-base - .frontend:rules:frontend_fixture needs: - !reference [.frontend-fixtures-base, needs] - "compile-test-assets" parallel: 7 # Uploads EE fixtures in the EE project. # Uploads FOSS fixtures in the FOSS project. upload-frontend-fixtures: variables: SETUP_DB: "false" extends: - .default-retry - .default-before_script - .repo-from-artifacts - .frontend:rules:upload-frontend-fixtures stage: fixtures needs: # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] script: - source scripts/gitlab_component_helpers.sh - export_fixtures_sha_for_upload - 'fixtures_archive_doesnt_exist || { echoinfo "INFO: Exiting early as package exists."; exit 0; }' - run_timed_command "create_fixtures_package" - run_timed_command "upload_fixtures_package" graphql-schema-dump: variables: SETUP_DB: "false" extends: - .default-retry - .ruby-cache - .default-before_script - .frontend:rules:default-frontend-jobs stage: fixtures needs: [] script: - bundle exec rake gitlab:graphql:schema:dump artifacts: expire_in: 30 days name: graphql-schema paths: - tmp/tests/graphql/gitlab_schema.graphql - tmp/tests/graphql/gitlab_schema.json .frontend-test-base: extends: - .default-retry - .yarn-cache variables: # Disable warnings in browserslist which can break on backports # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 BROWSERSLIST_IGNORE_OLD_DATA: "true" USE_BUNDLE_INSTALL: "false" SETUP_DB: "false" before_script: - !reference [.default-before_script, before_script] - yarn_install_script stage: test-frontend jest-build-cache: extends: - .frontend-test-base - .frontend:rules:jest needs: [] artifacts: name: jest-cache expire_in: 12h when: always paths: - tmp/cache/jest/ script: - run_timed_command "yarn jest:ci:build-cache" variables: # Propagate exit code correctly. See https://gitlab.com/groups/gitlab-org/-/epics/6074. FF_USE_NEW_BASH_EVAL_STRATEGY: 'true' FORCE_COLOR: '1' allow_failure: # In merge requests, failures exit with 2, so fail the pipeline. Otherwise, # they exit with 1, so as not to break master and other pipelines. exit_codes: 1 .vue3: variables: VUE_VERSION: 3 NODE_OPTIONS: --max-old-space-size=7680 allow_failure: true .with-jest-build-cache-vue3-needs: needs: - job: jest-build-cache-vue3 optional: true jest-build-cache-vue3: extends: - jest-build-cache - .frontend:rules:jest-vue3 - .vue3 jest: extends: - .frontend-test-base - .frontend:rules:jest needs: - job: jest-build-cache optional: true artifacts: name: coverage-frontend expire_in: 31d when: always paths: - coverage-frontend/ - junit_jest.xml - tmp/tests/frontend/ reports: junit: junit_jest.xml parallel: 11 script: - run_timed_command "yarn jest:ci:without-fixtures" jest-with-fixtures: extends: - jest - .repo-from-artifacts - .frontend:rules:jest needs: - !reference [jest, needs] # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] parallel: 2 script: - run_timed_command "yarn jest:ci:with-fixtures" jest vue3: extends: - jest - .frontend:rules:jest-vue3 - .vue3 needs: - !reference [.with-jest-build-cache-vue3-needs, needs] jest-with-fixtures vue3: extends: - jest-with-fixtures - .frontend:rules:jest-vue3 - .vue3 needs: - !reference ["jest vue3", needs] # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] jest predictive: extends: - jest - .frontend:rules:jest:predictive needs: - !reference [jest, needs] - "detect-tests" script: - if [[ -s "$RSPEC_CHANGED_FILES_PATH" ]] || [[ -s "$RSPEC_MATCHING_JS_FILES_PATH" ]]; then run_timed_command "yarn jest:ci:predictive-without-fixtures"; fi jest-with-fixtures predictive: extends: - jest-with-fixtures - .frontend:rules:jest:predictive needs: - !reference [jest-with-fixtures, needs] - "detect-tests" script: - if [[ -s "$RSPEC_CHANGED_FILES_PATH" ]] || [[ -s "$RSPEC_MATCHING_JS_FILES_PATH" ]]; then run_timed_command "yarn jest:ci:predictive-with-fixtures"; fi jest-integration: extends: - .frontend-test-base - .repo-from-artifacts - .frontend:rules:jest-integration script: - run_timed_command "yarn jest:integration --ci" needs: # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] - !reference [.with-graphql-schema-dump-needs, needs] jest-snapshot-vue3: extends: - .frontend-test-base - .repo-from-artifacts - .frontend:rules:jest-snapshot-vue3 needs: # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] variables: VUE_VERSION: 3 JEST_REPORT: jest-test-report.json SNAPSHOT_TEST_REPORT: jest-snapshot-test-report.json script: - | yarn jest:snapshots --ci --json --outputFile="${JEST_REPORT}" || echo 'Proceed to parsing test report...' echo $(ruby -rjson -e 'puts JSON.generate(JSON.parse(File.read(ENV["JEST_REPORT"])).dig("snapshot"))') > "${SNAPSHOT_TEST_REPORT}" echo " ============= snapshot test report start ==============" cat "${SNAPSHOT_TEST_REPORT}" echo " ============= snapshot test report end ================" snapshot_test_failed=$(ruby -rjson -e 'puts JSON.parse(File.read(ENV["SNAPSHOT_TEST_REPORT"])).dig("failure")') if [[ "${snapshot_test_failed}" == "true" ]] then echo "You have failed snapshot tests! Exiting 1..." exit 1 else echo 'All snapshot tests passed! Exiting 0...' exit 0 fi artifacts: name: snapshot_tests expire_in: 31d when: always paths: - jest-snapshot-test-match.json - jest-snapshot-test-report.json coverage-frontend: extends: - .default-retry - .default-utils-before_script - .yarn-cache - .repo-from-artifacts - .frontend:rules:coverage-frontend needs: - !reference [.repo-from-artifacts, needs] - job: "jest" optional: true - job: "jest-with-fixtures" optional: true - job: "jest predictive" optional: true stage: post-test script: - yarn_install_script - run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js" # Removing the individual coverage results, as we just merged them. - if ls coverage-frontend/jest-* > /dev/null 2>&1; then rm -r coverage-frontend/jest-*; fi coverage: '/^Statements\s*:\s*?(\d+(?:\.\d+)?)%/' artifacts: name: coverage-frontend expire_in: 31d paths: - coverage-frontend/ reports: coverage_report: coverage_format: cobertura path: coverage-frontend/cobertura-coverage.xml webpack-dev-server: extends: - .default-retry - .default-utils-before_script - .yarn-cache - .repo-from-artifacts - .frontend:rules:default-frontend-jobs stage: test-frontend variables: WEBPACK_MEMORY_TEST: "true" WEBPACK_VENDOR_DLL: "true" script: - yarn_install_script - run_timed_command "retry yarn webpack-vendor" - run_timed_command "node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js" artifacts: name: webpack-dev-server expire_in: 31d paths: - webpack-dev-server.json compile-storybook: extends: - .frontend-test-base - .storybook-yarn-cache - .repo-from-artifacts - .frontend:rules:compile-storybook stage: pages needs: # it's ok to wait for the repo artifact as we're waiting for the fixtures (which wait for the repo artifact) anyway - !reference [.repo-from-artifacts, needs] - !reference [.with-fixtures-needs, needs] - !reference [.with-graphql-schema-dump-needs, needs] artifacts: name: storybook expire_in: 31d when: always paths: - storybook/public script: - yarn_install_script_storybook - run_timed_command "yarn run storybook:build"