diff --git a/.circleci/config.yml b/.circleci/config.yml index 00870d86f5..6736ff3860 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,6 +32,24 @@ run_env_change: &run_env_change # Reload sysctl so these are in effect. # sudo sysctl -p +log_env: &log_env + name: Log Environment + command: | + echo "==> LBS Version" + lsb_release -a + echo "==> cat /etc/os-release" + cat /etc/os-release + echo "==> uname -srm" + uname -srm + echo "==> Node version: $(node --version)" + echo "==> NPM version: $(npm --version)" + echo "==> Meteor Node version: $(./meteor node --version)" + echo "==> Meteor NPM version: $(./meteor npm --version)" + echo "==> Dev bundle package.json:" + cat ./dev_bundle/lib/package.json + echo "==> Dev bundle node_modules:" + ls -l ./dev_bundle/lib/node_modules + # A reusable "run" snippet which enables the continued logging of memoryusage # to a file on disk which can be saved to build artifacts for later analysis. run_log_mem_use: &run_log_mem_use @@ -58,10 +76,10 @@ run_save_node_bin: &run_save_node_bin fi # This environment is set to every job (and the initial build). -build_machine_environment: &build_machine_environment - # Specify that we want an actual machine (ala Circle 1.0), not a Docker image. +build_machine_environment: + &build_machine_environment # Specify that we want an actual machine (ala Circle 1.0), not a Docker image. docker: - - image: meteor/circleci:android-30-node-14 + - image: meteor/circleci:2025.07.8-android-35-node-22 resource_class: large environment: # This multiplier scales the waitSecs for selftests. @@ -86,8 +104,8 @@ build_machine_environment: &build_machine_environment # These will be evaled before each command. PRE_TEST_COMMANDS: |- - ulimit -c unlimited; # Set core dump size as Ubuntu 14.04 lacks prlimit. - ulimit -a # Display all ulimit settings for transparency. + ulimit -c unlimited; # Set core dump size as Ubuntu 14.04 lacks prlimit. + ulimit -a # Display all ulimit settings for transparency. # This is only to make Meteor self-test not remind us that we can set # this argument for self-tests. @@ -97,29 +115,8 @@ build_machine_environment: &build_machine_environment NUM_GROUPS: 12 RUNNING_AVG_LENGTH: 6 -can_disable_fibers: &can_disable_fibers - parameters: - fibers: - type: boolean - default: true - -set_fibers_env: &set_fibers_env - name: "Disable Fibers" - command: | - if [ "<< parameters.fibers >>" == "false" ]; then - echo "Disabling Fibers" - echo 'export DISABLE_FIBERS=1' >> "$BASH_ENV" - source "$BASH_ENV" - fi - - -# Run tests with Fibers and then without. -matrix_for_fibers: &matrix_for_fibers - matrix: - parameters: - # If we want to run with Fibers and without, just append false here. - fibers: [true] - + # Force modern bundler test + METEOR_MODERN: true jobs: Get Ready: @@ -141,8 +138,16 @@ jobs: - run: name: Combine NPM Shrinkwrap Files command: | - for d in packages/*/.npm/package; do cat $d/npm-shrinkwrap.json >> shrinkwraps.txt; done - for d in packages/*/.npm/plugin/*; do cat $d/npm-shrinkwrap.json >> shrinkwraps.txt; done + for d in packages/*/.npm/package; do + if [ -f $d/npm-shrinkwrap.json ]; then + cat $d/npm-shrinkwrap.json >> shrinkwraps.txt; + fi + done + for d in packages/*/.npm/plugin/*; do + if [ -f $d/npm-shrinkwrap.json ]; then + cat $d/npm-shrinkwrap.json >> shrinkwraps.txt; + fi + done - restore_cache: keys: - package-npm-deps-cache-group1-v3-{{ checksum "shrinkwraps.txt" }} @@ -169,15 +174,19 @@ jobs: - run: name: Clear npm cache command: ./meteor npm cache clear --force + - run: + <<: *log_env - run: name: Get Ready command: | eval $PRE_TEST_COMMANDS; - pushd tools - npm install @types/node@14.17.6 --save-dev + cd dev_bundle/lib + ../../meteor npm install @types/node@22.7.4 --save-dev # Ensure that meteor/tools has no TypeScript errors. - ../meteor npx tsc --noEmit --skipLibCheck - popd + ../../meteor npm install -g typescript + cd ../../ + # tools/node_modules is a symlink, but starting on NPM 7, this symlinks are deleted https://github.com/npm/cli/issues/3669 + # so we are copying the node_modules to tools ./meteor --get-ready # shouldn't take longer than 60 minutes no_output_timeout: 60m @@ -192,7 +201,6 @@ jobs: path: /tmp/memuse.txt Isolated Tests: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -201,7 +209,6 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv @@ -214,6 +221,8 @@ jobs: --retries ${METEOR_SELF_TEST_RETRIES} \ --headless \ no_output_timeout: 20m + - run: + <<: *log_env - run: name: "Running self-test (Custom Warehouse Tests)" command: | @@ -236,7 +245,6 @@ jobs: path: /tmp/memuse.txt Test Group 0: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -245,10 +253,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 0)" command: | @@ -278,7 +287,6 @@ jobs: path: /tmp/memuse.txt Test Group 1: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -287,10 +295,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 1)" command: | @@ -320,7 +329,6 @@ jobs: path: /tmp/memuse.txt Test Group 2: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -329,7 +337,8 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env + - run: + <<: *log_env - run: name: "Print environment" command: printenv @@ -339,6 +348,9 @@ jobs: if [ -f ./tmp/test-groups/2.txt ]; then TEST_GROUP=$(<./tmp/test-groups/2.txt); elif [ -f ./tmp/test-groups/0.txt ]; then TEST_GROUP=XXXXX; else TEST_GROUP='^co[n-z]'; fi echo $TEST_GROUP; eval $PRE_TEST_COMMANDS; + export PATH="/home/circleci/.sdkman/candidates/gradle/8.7/bin:${PATH}" + java --version + gradle --version ./meteor self-test \ "$TEST_GROUP" \ --retries ${METEOR_SELF_TEST_RETRIES} \ @@ -362,7 +374,6 @@ jobs: path: /tmp/memuse.txt Test Group 3: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -371,7 +382,8 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env + - run: + <<: *log_env - run: name: "Print environment" command: printenv @@ -404,7 +416,6 @@ jobs: path: /tmp/memuse.txt Test Group 4: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -413,10 +424,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 4)" command: | @@ -446,7 +458,6 @@ jobs: path: /tmp/memuse.txt Test Group 5: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -455,10 +466,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 5)" command: | @@ -488,7 +500,6 @@ jobs: path: /tmp/memuse.txt Test Group 6: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -497,10 +508,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 6)" command: | @@ -530,7 +542,6 @@ jobs: path: /tmp/memuse.txt Test Group 7: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -539,10 +550,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 7)" command: | @@ -572,7 +584,6 @@ jobs: path: /tmp/memuse.txt Test Group 8: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -581,10 +592,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 8)" command: | @@ -614,7 +626,6 @@ jobs: path: /tmp/memuse.txt Test Group 9: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -623,10 +634,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 9)" command: | @@ -656,7 +668,6 @@ jobs: path: /tmp/memuse.txt Test Group 10: - <<: *can_disable_fibers <<: *build_machine_environment steps: - run: @@ -665,10 +676,11 @@ jobs: <<: *run_env_change - attach_workspace: at: . - - run: *set_fibers_env - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 10)" command: | @@ -709,6 +721,8 @@ jobs: - run: name: "Print environment" command: printenv + - run: + <<: *log_env - run: name: "Running self-test (Test Group 11)" command: | @@ -722,7 +736,7 @@ jobs: --headless \ --junit ./tmp/results/junit/11.xml \ --without-tag "custom-warehouse" - no_output_timeout: 30m + no_output_timeout: 35m - run: <<: *run_save_node_bin - store_test_results: @@ -737,47 +751,38 @@ jobs: - store_artifacts: path: /tmp/memuse.txt - # Test the JSDoc declarations which live within this codebase against the - # Meteor Docs (https://github.com/meteor/docs) repository, where they'll - # eventually be consumed. This test aims to provide an early warning of - # potentially breaking changes, so they aren't discovered when the docs are - # next updated, which generally occurs during major Meteor version releases - # (for example, 1.4 to 1.5, 1.5 to 1.6). + # Test the JSDoc declarations which live within this codebase. + # Now the docs live in this repo, we can test them here, every PR is tested. Docs: docker: # This Node version should match that in the meteor/docs CircleCI config. - - image: meteor/circleci:android-28-node-12 + - image: meteor/circleci:2025.07.8-android-35-node-22 resource_class: large environment: CHECKOUT_METEOR_DOCS: /home/circleci/test_docs + <<: *build_machine_environment steps: - run: - name: Cloning "meteor/docs" Repository's "update-to-meteor-1.9" branch + name: Cloning "meteor" Repository's current branch command: | - git clone --branch update-to-meteor-1.9 https://github.com/meteor/docs.git ${CHECKOUT_METEOR_DOCS} - # The "docs" repository normally brings in the Meteor code as a Git - # submodule checked out into the "code" directory. As the goal of this - # test is to run it against the _current_ repository's code, we'll move - # the "code" directory out of the way and move the checkout (of meteor) - # into that directory, rather than the default $CIRCLE_WORKING_DIRECTORY. - - checkout - - run: - name: Move Meteor checkout into docs repository's "code" directory - command: | - rmdir "${CHECKOUT_METEOR_DOCS}/code" - # $CIRCLE_WORKING_DIRECTORY uses a tilde, so expand it to $HOME. - mv "${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}" \ - "${CHECKOUT_METEOR_DOCS}/code" + if [[ -n "$CIRCLE_PULL_REQUEST" ]]; then + PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | sed 's|.*/pull/\([0-9]*\)|\1|') + PR_BRANCH=$(curl -s https://api.github.com/repos/meteor/meteor/pulls/$PR_NUMBER | jq -r .head.ref) + git clone https://github.com/meteor/meteor.git ${CHECKOUT_METEOR_DOCS} + cd ${CHECKOUT_METEOR_DOCS} + git fetch origin pull/$PR_NUMBER/head:$PR_BRANCH + else + git clone --branch $CIRCLE_BRANCH https://github.com/meteor/meteor.git ${CHECKOUT_METEOR_DOCS} + fi # Run almost the same steps the meteor/docs repository runs, minus deploy. - run: name: Generating Meteor documentation for JSDoc testing command: | - cd ${CHECKOUT_METEOR_DOCS} + cd ${CHECKOUT_METEOR_DOCS}/docs npm install npm test Clean Up: - <<: *can_disable_fibers <<: *build_machine_environment steps: - attach_workspace: @@ -860,58 +865,45 @@ workflows: - Docs - Get Ready - Isolated Tests: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 0: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 1: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 2: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 3: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 4: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 5: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 6: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 7: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 8: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 9: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 10: - <<: *matrix_for_fibers requires: - Get Ready - Test Group 11: requires: - Get Ready - Clean Up: - <<: *matrix_for_fibers requires: - Isolated Tests - Test Group 0 diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..e023176dc5 --- /dev/null +++ b/.envrc @@ -0,0 +1,113 @@ +#!/bin/env zsh + +# +# Commands and shortcuts for Meteor core development, you can load these in your terminal by running `source .envrc`. +# Or by adding `[[ -s .envrc ]] && source .envrc` to your `.zshrc` or `.bashrc`. +# + +export ROOT_DIR=$(git rev-parse --show-toplevel) + +######## +# Core # +######## + +function @meteor { + "$ROOT_DIR/meteor" "$@" +} + +function @get-ready { + @meteor --get-ready +} + +function @test-packages { + TINYTEST_FILTER="$1" @meteor test-packages --exclude-archs=web.browser.legacy,web.cordova +} + +function @test-self { + @meteor self-test "$@" +} + +function @test-in-console { + "$ROOT_DIR/packages/test-in-console/run.sh" "$@" +} + +function @check-syntax { + node "$ROOT_DIR/scripts/admin/check-legacy-syntax/check-syntax.js" +} + +function @generate-dev-bundle { + rm -rf $ROOT_DIR/dev_bundle* + "$ROOT_DIR/scripts/generate-dev-bundle.sh" +} + +function @init-submodule { + git submodule update --init --recursive +} + +################# +# Documentation # +################# + +function @docs-start { + npm run docs:dev --prefix "$ROOT_DIR/v3-docs/docs" +} + +function @docs-migration-start { + npm run docs:dev --prefix "$ROOT_DIR/v3-docs/v3-migration-docs" +} + +function @get-changes { + git diff --numstat HEAD~1 HEAD | awk '($1 + $2) <= 5000 {print $3}' +} + +function @summarize-changes { + changes=$(@get-changes) + + if [ -n "$changes" ]; then + changes=$(git diff HEAD~1 HEAD -- $(echo "$changes" | tr '\n' ' ')) + else + changes=$(git diff HEAD~1 HEAD) + fi + + echo "$changes" | llm -s "Summarize the following changes in a few sentences:" +} + +function @packages-bumped { + git diff --name-only devel...$(git branch --show-current) | grep "packages/.*/package.js$" | while IFS= read -r file; do + if ! git show devel:$file > /dev/null 2>&1; then + continue + fi + + old=$(git show devel:$file | grep -o "version: *['\"][^'\"]*['\"]" | sed "s/version: *.['\"]//;s/['\"].*//") + version=$(grep -o "version: *['\"][^'\"]*['\"]" "$file" | sed "s/version: *.['\"]//;s/['\"].*//") + name=$(grep -o "name: *['\"][^'\"]*['\"]" "$file" | sed "s/name: *.['\"]//;s/['\"].*//") + + pkg_name=$(echo "$file" | sed -E 's|packages/([^/]*/)?([^/]*)/package\.js|\2|') + + version_in_red=$(tput setaf 1)$version$(tput sgr0) + + if [[ "$version" != "$old" ]]; then + echo "- $pkg_name@$version_in_red" + fi + done +} + +function @packages-bumped-npm { + git diff --name-only devel...$(git branch --show-current) | grep "npm-packages/.*/package.json$" | while IFS= read -r file; do + if ! git show devel:$file > /dev/null 2>&1; then + continue + fi + + old=$(git show devel:$file | grep -o "version: *['\"][^'\"]*['\"]" | sed "s/version: *.['\"]//;s/['\"].*//") + version=$(grep -o "\"version\": *['\"][^'\"]*['\"]" "$file" | sed "s/\"version\": *.['\"]//;s/['\"].*//") + name=$(grep -o "\"name\": *['\"][^'\"]*['\"]" "$file" | sed "s/\"name\": *.['\"]//;s/['\"].*//") + + pkg_name=$(echo "$file" | sed -E 's|npm-packages/([^/]*/)?([^/]*)/package\.json|\2|') + + version_in_red=$(tput setaf 1)$version$(tput sgr0) + + if [[ "$version" != "$old" ]]; then + echo "- $pkg_name@$version_in_red" + fi + done +} diff --git a/.eslintignore b/.eslintignore index 3653ab7c32..a62c426997 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,9 +2,7 @@ android_bundle/ dev_bundle/ docs/ examples/ -packages/ scripts/ -tools/ !tools/*.js !tools/isobuild/*.js !tools/catalog/*.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..ec54d801f0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +@henriquealbert @denihs @fredmaiaarantes @nachocodoner @leonardoventurini diff --git a/.github/labeler.yml b/.github/labeler.yml index b99cd8fb97..343cc5ee6a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,120 +1,178 @@ Project:Accounts:Password: - - packages/accounts-password/**/* + - changed-files: + - any-glob-to-any-file: packages/accounts-password/**/* Project:Accounts:UI: - - packages/meteor-developer-config-ui/**/* - - packages/github-config-ui/**/* - - packages/google-config-ui/**/* - - packages/twitter-config-ui/**/* - - packages/facebook-config-ui/**/* - - packages/accounts-ui/**/* - - packages/accounts-ui-unstyled/**/* + - changed-files: + - any-glob-to-any-file: + - packages/meteor-developer-config-ui/**/* + - packages/github-config-ui/**/* + - packages/google-config-ui/**/* + - packages/twitter-config-ui/**/* + - packages/facebook-config-ui/**/* + - packages/accounts-ui/**/* + - packages/accounts-ui-unstyled/**/* Project:CSS: - - packages/non-core/less/**/* - - packages/minifier-css/**/* - - packages/standard-minifier-css/**/* + - changed-files: + - any-glob-to-any-file: + - packages/non-core/less/**/* + - packages/minifier-css/**/* + - packages/standard-minifier-css/**/* Project:DDP: - - packages/ddp-common/**/* - - packages/ddp-rate-limiter/**/* - - packages/ddp-server/**/* - - packages/ddp-client/**/* - - packages/ddp/**/* - - packages/socket-stream-client/**/* + - changed-files: + - any-glob-to-any-file: + - packages/ddp-common/**/* + - packages/ddp-rate-limiter/**/* + - packages/ddp-server/**/* + - packages/ddp-client/**/* + - packages/ddp/**/* + - packages/socket-stream-client/**/* Project:EJSON: - - packages/ejson/**/* + - changed-files: + - any-glob-to-any-file: packages/ejson/**/* Project:HMR: - - packages/hot-code-push/**/* - - packages/hot-module-replacement/**/* + - changed-files: + - any-glob-to-any-file: + - packages/hot-code-push/**/* + - packages/hot-module-replacement/**/* Project:Isobuild:Minifiers: - - packages/minifier-css/**/* - - packages/minifier-js/**/* - - packages/standard-minifier-js/**/* - - packages/standard-minifier-css/**/* - - packages/standard-minifiers/**/* + - changed-files: + - any-glob-to-any-file: + - packages/minifier-css/**/* + - packages/minifier-js/**/* + - packages/standard-minifier-js/**/* + - packages/standard-minifier-css/**/* + - packages/standard-minifiers/**/* Project:Isobuild: - - tools/isobuild/**/* + - changed-files: + - any-glob-to-any-file: + - tools/isobuild/**/* Project:JS Environment:Typescript: - - packages/typescript/**/* + - changed-files: + - any-glob-to-any-file: + - packages/typescript/**/* Project:JS Environment: - - packages/babel-compiler/**/* - - packages/babel-runtime/**/* - - packages/ecmascript/**/* - - packages/ecmascript-runtime/**/* - - packages/ecmascript-runtime-client/**/* - - packages/ecmascript-runtime-server/**/* - - packages/es5-shim/**/* - - packages/jshint/**/* + - changed-files: + - any-glob-to-any-file: + - packages/babel-compiler/**/* + - packages/babel-runtime/**/* + - packages/ecmascript/**/* + - packages/ecmascript-runtime/**/* + - packages/ecmascript-runtime-client/**/* + - packages/ecmascript-runtime-server/**/* + - packages/es5-shim/**/* + - packages/jshint/**/* Project:Livequery: - - packages/livedata/**/* + - changed-files: + - any-glob-to-any-file: + - packages/livedata/**/* Project:Minimongo: - - packages/minimongo + - changed-files: + - any-glob-to-any-file: + - packages/minimongo Project:Mobile: - - tools/cordova/**/* - - packages/launch-screen/**/* - - packages/mobile-experience/**/* - - packages/mobile-status-bar/**/* + - changed-files: + - any-glob-to-any-file: + - tools/cordova/**/* + - packages/launch-screen/**/* + - packages/mobile-experience/**/* + - packages/mobile-status-bar/**/* Project:Mongo Driver: - - packages/mongo/**/* - - packages/mongo-dev-server/**/* - - packages/mongo-id/**/* - - packages/mongo-livedata/**/* - - packages/disable-oplog/**/* - - packages/non-core/mongo-decimal/**/* + - changed-files: + - any-glob-to-any-file: + - packages/mongo/**/* + - packages/mongo-dev-server/**/* + - packages/mongo-id/**/* + - packages/mongo-livedata/**/* + - packages/disable-oplog/**/* + - packages/non-core/mongo-decimal/**/* Project:NPM: - - npm-packages/**/* + - changed-files: + - any-glob-to-any-file: + - npm-packages/**/* Project:Release Process: - - scripts/**/* + - changed-files: + - any-glob-to-any-file: + - scripts/**/* Project:Tool: - - tools/**/* - - packages/meteor-tool/**/* + - changed-files: + - any-glob-to-any-file: + - tools/**/* + - packages/meteor-tool/**/* Project:Tool:Shell: - - tools/console/**/* + - changed-files: + - any-glob-to-any-file: + - tools/console/**/* Project:Utilities:Email: - - packages/email/**/* + - changed-files: + - any-glob-to-any-file: + - packages/email/**/* Project:Utilities:HTTP: - - packages/deprecated/http/**/* - - packages/fetch/**/* - - packages/url/**/* + - changed-files: + - any-glob-to-any-file: + - packages/deprecated/http/**/* + - packages/fetch/**/* + - packages/url/**/* Project:Webapp: - - packages/webapp/**/* - - packages/webapp-hashing/**/* + - changed-files: + - any-glob-to-any-file: + - packages/webapp/**/* + - packages/webapp-hashing/**/* Project:Windows: - - scripts/windows/**/* + - changed-files: + - any-glob-to-any-file: + - scripts/windows/**/* Project:Webapp:Browser Policy: - - packages/browser-policy/**/* - - packages/browser-policy-common/**/* - - packages/browser-policy-content/**/* - - packages/browser-policy-framing/**/* + - changed-files: + - any-glob-to-any-file: + - packages/browser-policy/**/* + - packages/browser-policy-common/**/* + - packages/browser-policy-content/**/* + - packages/browser-policy-framing/**/* Project:Examples: - - tools/cli/example-repositories.js + - changed-files: + - any-glob-to-any-file: + - tools/cli/example-repositories.js Project:Dynamic Import: - - packages/dynamic-import/**/* + - changed-files: + - any-glob-to-any-file: + - packages/dynamic-import/**/* Project:Docs: - - docs/**/* + - changed-files: + - any-glob-to-any-file: + - docs/**/* + - v3-docs/**/* Project:Guide: - - guide/**/* + - changed-files: + - any-glob-to-any-file: + - guide/**/* + +github_actions: + - changed-files: + - any-glob-to-any-file: + - ./github/**/* diff --git a/.github/scripts/__tests__/inactive-issues.test.js b/.github/scripts/__tests__/inactive-issues.test.js new file mode 100644 index 0000000000..91f9ddf60f --- /dev/null +++ b/.github/scripts/__tests__/inactive-issues.test.js @@ -0,0 +1,198 @@ +// Tests for inactive-issues.js using Node's built-in test runner (node:test) +// We only care about the last comments (per user instruction), so we don't need pagination logic. + +const { test, beforeEach } = require('node:test'); +const assert = require('node:assert'); +const path = require('node:path'); + +// Load the script dynamically so we can pass mocks. +const scriptPath = path.join(__dirname, '..', 'inactive-issues.js'); + +// Helper to advance days +const daysAgo = (days) => { + const d = new Date(); + d.setUTCDate(d.getUTCDate() - days); + return d.toISOString(); +}; + +// Factory for github REST mock structure +function buildGithubMock({ issues, commentsByIssue }) { + return { + rest: { + issues: { + listForRepo: async ({ page, per_page }) => { + // simple pagination slice + const start = (page - 1) * per_page; + const end = start + per_page; + return { data: issues.slice(start, end) }; + }, + listComments: async ({ issue_number }) => { + return { data: commentsByIssue[issue_number] || [] }; + }, + createComment: async ({ issue_number, body }) => { + // push comment to structure to allow assertions on side effects if needed + const arr = commentsByIssue[issue_number] || (commentsByIssue[issue_number] = []); + arr.push({ + id: Math.random(), + body, + created_at: new Date().toISOString(), + user: { login: 'github-actions[bot]', type: 'Bot' } + }); + return {}; + }, + addLabels: async ({ issue_number, labels }) => { + const issue = issues.find(i => i.number === issue_number); + if (issue) { + (issue.labels || (issue.labels = [])).push(...labels.map(l => ({ name: l }))); + } + return {}; + } + } + } + }; +} + +// Wrap script invocation for reuse +async function runScript({ issues, commentsByIssue }) { + delete require.cache[require.resolve(scriptPath)]; + const fn = require(scriptPath); + const github = buildGithubMock({ issues, commentsByIssue }); + await fn({ github, context: { repo: { owner: 'meteor', repo: 'meteor' } } }); + return { issues, commentsByIssue }; +} + +let baseIssueNumber = 1000; +function makeIssue({ daysSinceHumanActivity, isPR = false, labels = [], user = 'user1' }) { + // We'll simulate by setting created_at to the human activity date if no comments. + const updated_at = daysAgo(daysSinceHumanActivity); + return { + number: baseIssueNumber++, + pull_request: isPR ? {} : undefined, + labels: labels.map(n => ({ name: n })), + user: { login: user }, + created_at: daysAgo(daysSinceHumanActivity), + updated_at + }; +} + +// TESTS + +beforeEach(() => { + baseIssueNumber = 1000; +}); + +test('60 days inactivity -> adds reminder comment (no prior reminder)', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 60 }); + const issues = [issue]; + const commentsByIssue = { [issue.number]: [] }; // no comments + + await runScript({ issues, commentsByIssue }); + + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 1, 'Should have 1 reminder comment'); + assert.match(botComments[0].body, /60 days/); + assert.ok(!issue.labels.some(l => l.name === 'idle'), 'Should not label yet'); +}); + +test('60 days inactivity but already reminded -> no duplicate comment', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 65 }); + const issues = [issue]; + const commentsByIssue = { + [issue.number]: [ + { + id: 1, + body: 'π @user1 This issue has been open with no human activity for 60 days. Is this issue still relevant? If there is no human response or activity within the next 30 days, this issue will be labeled as `idle`.', + created_at: daysAgo(5), // 5 days ago bot comment (means last human is 65 days, bot after human) + user: { login: 'github-actions[bot]', type: 'Bot' } + } + ] + }; + + await runScript({ issues, commentsByIssue }); + + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 1, 'Should still have only the existing reminder'); +}); + +test('90 days inactivity -> label + comment', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 95 }); + const issues = [issue]; + const commentsByIssue = { [issue.number]: [] }; + + await runScript({ issues, commentsByIssue }); + + assert.ok(issue.labels.some(l => l.name === 'idle'), 'Should add idle label'); + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 1, 'Should comment when labeling'); + assert.match(botComments[0].body, /90 days/i); +}); + +test('90 days inactivity but already labeled -> no action', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 100, labels: ['idle'] }); + const issues = [issue]; + const commentsByIssue = { [issue.number]: [] }; + + await runScript({ issues, commentsByIssue }); + + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 0, 'Should not comment again'); +}); + +test('90 days inactivity but already labeled `in-development` -> no action', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 100, labels: ['in-development'] }); + const issues = [issue]; + const commentsByIssue = { [issue.number]: [] }; + + await runScript({ issues, commentsByIssue }); + + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 0, 'Should not comment again'); +}); + + +test('Human reply after reminder resets cycle (no immediate labeling)', async () => { + // Scenario: last human activity 10 days ago, bot commented 40 days ago (which was 50 days after original). Should NOT comment again or label. + const issue = makeIssue({ daysSinceHumanActivity: 10 }); + const issues = [issue]; + const commentsByIssue = { + [issue.number]: [ + { + id: 1, + body: 'π @user1 This issue has been open with no human activity for 60 days... ', + created_at: daysAgo(50), + user: { login: 'github-actions[bot]', type: 'Bot' } + }, + { + id: 2, + body: 'I am still seeing this problem', + created_at: daysAgo(10), + user: { login: 'some-human', type: 'User' } + } + ] + }; + + await runScript({ issues, commentsByIssue }); + + const botComments = commentsByIssue[issue.number].filter(c => c.user.login === 'github-actions[bot]'); + assert.equal(botComments.length, 1, 'Should not add a new bot comment'); + assert.ok(!issue.labels.some(l => l.name === 'idle'), 'Should not label'); +}); + +test('Only bot comments (no human ever) counts from creation date', async () => { + const issue = makeIssue({ daysSinceHumanActivity: 61 }); + const issues = [issue]; + const commentsByIssue = { + [issue.number]: [ + { + id: 1, + body: 'Automated maintenance notice', + created_at: daysAgo(30), + user: { login: 'github-actions[bot]', type: 'Bot' } + } + ] + }; + + await runScript({ issues, commentsByIssue }); + const botComments = commentsByIssue[issue.number].filter(c => /60 days/.test(c.body)); + assert.equal(botComments.length, 1, 'Should add a 60-day reminder'); +}); diff --git a/.github/scripts/inactive-issues.js b/.github/scripts/inactive-issues.js new file mode 100644 index 0000000000..a75f5b81a1 --- /dev/null +++ b/.github/scripts/inactive-issues.js @@ -0,0 +1,200 @@ +/** +* Mark issues as idle after a period of inactivity +* and post reminders after a shorter period of inactivity. +* +* 1. Issues with no human activity for 60 days get a reminder comment. +* 2. Issues with no human activity for 90 days get labeled as "idle" and get a comment. +* +* Human activity is defined as any comment from a non-bot user. +* +* This script is intended to be run as a GitHub Action on a schedule (e.g., daily). + */ +module.exports = async ({ github, context }) => { + const daysToComment = 60; + const daysToLabel = 90; + + const idleTimeComment = daysToComment * 24 * 60 * 60 * 1000; + const idleTimeLabel = daysToLabel * 24 * 60 * 60 * 1000; + const now = new Date(); + + const BOT_LOGIN = 'github-actions[bot]'; + const REMINDER_PHRASE = 'Is this issue still relevant?'; + + const COMMENT_60_TEMPLATE = (login) => + `π @${login} This issue has been open with no human activity for ${daysToComment} days. Is this issue still relevant? If there is no human response or activity within the next ${daysToLabel - daysToComment} days, this issue will be labeled as \`idle\`.`; + + const COMMENT_90_TEXT = + 'This issue has been automatically labeled as `idle` due to 90 days of inactivity (no human interaction). If this is still relevant or if someone is working on it, please comment or add `in-development` label.'; + + // Fetch all open issues + async function fetchAllIssues() { + let page = 1; + const per_page = 100; + const results = []; + let keepGoing = true; + + while (keepGoing) { + const { data } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page, + page, + sort: 'updated', + direction: 'asc' + }); + + if (!data.length) break; + results.push(...data); + + if (data.length < per_page) { + keepGoing = false; + } else { + page++; + await new Promise((r) => setTimeout(r, 120)); + } + } + return results; + } + // analyse comments to find last human activity and if a reminder was already posted after that + async function analyzeComments(issueNumber, issueCreatedAt) { + const commentsResp = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + per_page: 100 + }); + + const comments = commentsResp.data; + let lastHumanActivity = null; + + for (let i = comments.length - 1; i >= 0; i--) { + const c = comments[i]; + const isBot = c.user?.type === 'Bot' || c.user?.login === BOT_LOGIN; + if (!isBot) { + lastHumanActivity = new Date(c.created_at); + break; + } + } + + if (!lastHumanActivity) { + lastHumanActivity = new Date(issueCreatedAt); + } + + const hasReminderAfterLastHuman = comments.some( + (c) => + c.user?.login === BOT_LOGIN && + c.body?.includes(REMINDER_PHRASE) && + new Date(c.created_at) > lastHumanActivity + ); + + return { lastHumanActivity, hasReminderAfterLastHuman }; + } + + const issues = await fetchAllIssues(); + + let processed = 0; + let commented = 0; + let labeled = 0; + let skippedPR = 0; + + for (const issue of issues) { + processed++; + + if (issue.pull_request) { + skippedPR++; + continue; + } + + if (issue.labels.some((l) => l.name === 'idle' || l.name === 'in-development')) { + continue; + } + + let analysis; + try { + analysis = await analyzeComments(issue.number, issue.created_at); + } catch (err) { + continue; // fail to get comments, skip + } + + const { lastHumanActivity, hasReminderAfterLastHuman } = analysis; + const inactivityMs = now.getTime() - lastHumanActivity.getTime(); + + // 90+ days => label + comment + if (inactivityMs >= idleTimeLabel) { + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: ['idle'] + }); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: COMMENT_90_TEXT + }); + labeled++; + continue; + } catch (err) { + // retry simples + try { + await new Promise((r) => setTimeout(r, 5000)); + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: ['idle'] + }); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: COMMENT_90_TEXT + }); + labeled++; + } catch {} + continue; + } + } + + // 60-89 days => comment (once) + if ( + inactivityMs >= idleTimeComment && + inactivityMs < idleTimeLabel && + !hasReminderAfterLastHuman + ) { + const body = COMMENT_60_TEMPLATE(issue.user.login); + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body + }); + commented++; + } catch (err) { + try { + await new Promise((r) => setTimeout(r, 5000)); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body + }); + commented++; + } catch {} + } + } + } + + // Log summary for CI + console.log( + JSON.stringify( + { processed, commented, labeled, skippedPR }, + null, + 2 + ) + ); +}; diff --git a/.github/workflows/check-code-style.yml b/.github/workflows/check-code-style.yml index 0a136db59a..8b24944b3f 100644 --- a/.github/workflows/check-code-style.yml +++ b/.github/workflows/check-code-style.yml @@ -11,9 +11,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: 22.x - run: npm ci - name: Run ESLint@8 run: npx eslint@8 "./npm-packages/meteor-installer/**/*.js" diff --git a/.github/workflows/check-syntax.yml b/.github/workflows/check-syntax.yml index 91051b2789..a20bb011ca 100644 --- a/.github/workflows/check-syntax.yml +++ b/.github/workflows/check-syntax.yml @@ -1,15 +1,14 @@ name: Check legacy syntax on: - - push - pull_request jobs: check-code-style: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22.x - run: cd scripts/admin/check-legacy-syntax && npm ci - name: Check syntax - run: cd scripts/admin/check-legacy-syntax && node check-syntax.js + run: cd scripts/admin/check-legacy-syntax && node check-syntax.js diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3c7f7d5ec9..dc85db922f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,13 +11,13 @@ jobs: working-directory: docs/ steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 12.x - name: Build the Docs run: npm ci && npm run build - name: Deploy to Netlify for preview - uses: nwtgck/actions-netlify@v1.2.4 + uses: nwtgck/actions-netlify@v2.1.0 with: publish-dir: './docs/public/' production-branch: devel diff --git a/.github/workflows/guide.yml b/.github/workflows/guide.yml index bbc5bbd023..bd3d801966 100644 --- a/.github/workflows/guide.yml +++ b/.github/workflows/guide.yml @@ -11,13 +11,13 @@ jobs: working-directory: guide/ steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 12.x + node-version: 22.x - name: Build the Guide run: npm ci && npm run build - name: Deploy to Netlify for preview - uses: nwtgck/actions-netlify@v1.2.4 + uses: nwtgck/actions-netlify@v2.1.0 with: publish-dir: './guide/public' production-branch: devel diff --git a/.github/workflows/inactive-issues.yml b/.github/workflows/inactive-issues.yml new file mode 100644 index 0000000000..2d8cba7a3f --- /dev/null +++ b/.github/workflows/inactive-issues.yml @@ -0,0 +1,24 @@ +name: Inactive Issues Management + +on: + schedule: + # βAt 01:00 on Saturday.β + - cron: '0 1 * * 6' + # Allows to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + manage-inactive-issues: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Manage inactive issues + uses: actions/github-script@v6 + with: + script: | + const script = require('./.github/scripts/inactive-issues.js') + await script({github, context}) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index a9d25b1e47..da6690818c 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -17,6 +17,6 @@ jobs: label: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v4 + - uses: actions/labeler@v5 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/npm-eslint-plugin-meteor.yml b/.github/workflows/npm-eslint-plugin-meteor.yml index 15e48abf2c..ff51a2e847 100644 --- a/.github/workflows/npm-eslint-plugin-meteor.yml +++ b/.github/workflows/npm-eslint-plugin-meteor.yml @@ -16,15 +16,12 @@ jobs: defaults: run: working-directory: npm-packages/eslint-plugin-meteor - strategy: - matrix: - node-version: [12.x, 14.x] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: 22.x cache: npm - run: npm ci - run: npm test diff --git a/.github/workflows/npm-meteor-babel.yml b/.github/workflows/npm-meteor-babel.yml index 6d65273cf3..61bb203ccb 100644 --- a/.github/workflows/npm-meteor-babel.yml +++ b/.github/workflows/npm-meteor-babel.yml @@ -16,15 +16,12 @@ jobs: defaults: run: working-directory: npm-packages/meteor-babel - strategy: - matrix: - node-version: [12.x, 14.x] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: 14.x cache: npm - run: npm ci - run: npm run test diff --git a/.github/workflows/npm-meteor-promise.yml b/.github/workflows/npm-meteor-promise.yml index 4ad4f6df7c..4eb16400a1 100644 --- a/.github/workflows/npm-meteor-promise.yml +++ b/.github/workflows/npm-meteor-promise.yml @@ -18,11 +18,11 @@ jobs: working-directory: npm-packages/meteor-promise strategy: matrix: - node-version: [12.x, 14.x] + node-version: [14.x] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: npm diff --git a/.github/workflows/run-profiler.yml b/.github/workflows/run-profiler.yml new file mode 100644 index 0000000000..c19ff83a7d --- /dev/null +++ b/.github/workflows/run-profiler.yml @@ -0,0 +1,46 @@ +name: Run Profiler + +on: + issue_comment: + types: [created] + +jobs: + run-profiler: + if: github.event.issue.pull_request && contains(github.event.comment.body , '/profile') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Checkout Pull Request + run: gh pr checkout ${{ github.event.issue.number }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v4 + with: + node-version: 22.x + + - name: Set ENVs + run: | + value="VALUE" + echo "Key=$value" >> $GITHUB_ENV + + PR_NUMBER="${{ github.event.issue.number }}" + echo "PrNumber=$PR_NUMBER" >> $GITHUB_ENV + + - name: Run CI + run: | + echo "Running meteor profiler..." + echo $PR_NUMBER + git status + ls + + - name: Comment PR + uses: thollander/actions-comment-pull-request@v3 + with: + message: | + Hello world !!!! :wave: + this is pr number: #${{ env.PrNumber }} + testing value: ${{ env.Key }} + pr-number: ${{ github.event.issue.number }} diff --git a/.github/workflows/test-deprecated-packages.yml b/.github/workflows/test-deprecated-packages.yml new file mode 100644 index 0000000000..e4ed12fe92 --- /dev/null +++ b/.github/workflows/test-deprecated-packages.yml @@ -0,0 +1,52 @@ +name: Test Deprecated Packages + +# Disabled until we figure out how to fix the error from puppeteer +# Runs on Travis CI for now +# +#on: +# push: +# branches: +# - main +# pull_request: + +jobs: + build: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.head_ref }}-test-deprecated-packages + cancel-in-progress: true + timeout-minutes: 60 + + env: + PUPPETEER_DOWNLOAD_PATH: /home/runner/.npm/chromium + + steps: + - name: Update and install dependencies + run: sudo apt-get update && sudo apt-get install -y libnss3 g++-12 + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 20.15.1 + + - name: Cache Node.js modules + uses: actions/cache@v3 + with: + path: | + ~/.npm + .meteor + .babel-cache + dev_bundle + /home/runner/.npm/chromium + key: ${{ runner.os }}-node-${{ hashFiles('meteor', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install dependencies + run: npm install + + - name: Run tests + run: ./packages/test-in-console/run.sh \ No newline at end of file diff --git a/.github/workflows/windows-selftest.yml b/.github/workflows/windows-selftest.yml new file mode 100644 index 0000000000..37d739d7c8 --- /dev/null +++ b/.github/workflows/windows-selftest.yml @@ -0,0 +1,81 @@ +name: Windows Selftest + +on: + pull_request: + types: + - opened + - reopened + - synchronize + paths: + - 'meteor' + - 'meteor.bat' + - 'tools/**' + - 'packages/babel-compiler/**' + - 'packages/dynamic-import/**' + - 'packages/meteor/**' + - 'packages/meteor-tool/**' + - '.github/workflows/windows-selftest.yml' + + push: + branches: + - devel + +env: + METEOR_PRETTY_OUTPUT: 0 + SELF_TEST_TOOL_NODE_FLAGS: ' ' + TOOL_NODE_FLAGS: --expose-gc + TIMEOUT_SCALE_FACTOR: 20 + METEOR_HEADLESS: true + SELF_TEST_EXCLUDE: '^NULL-LEAVE-THIS-HERE-NULL$' + METEOR_MODERN: true + +jobs: + test: + runs-on: windows-2019-meteor + concurrency: + group: ${{ github.head_ref }}-meteor-selftest-windows + cancel-in-progress: true + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 22.x + + - name: Cache dependencies + id: meteor-cache + uses: actions/cache@v4 + with: + path: | + dev_bundle/ + .babel-cache/ + .meteor/ + ~/.npm + node_modules/ + packages/**/.npm + key: ${{ runner.os }}-meteor-${{ hashFiles('**/package-lock.json', 'meteor', 'meteor.bat') }} + restore-keys: | + ${{ runner.os }}-meteor- + + - name: Install dependencies + shell: pwsh + run: | + $env:PATH = "C:\Program Files\7-Zip;$env:PATH" + .\scripts\windows\ci\install.ps1 + + # Run ONLY when the cache was NOT restored + - name: Prepare Meteor (cache miss) + if: steps.meteor-cache.outputs.cache-hit != 'true' + shell: pwsh + run: | + $env:PATH = "C:\Program Files\7-Zip;$env:PATH" + .\meteor.bat --get-ready + + - name: Run tests + shell: pwsh + run: | + $env:PATH = "C:\Program Files\7-Zip;$env:PATH" + .\scripts\windows\ci\test.ps1 diff --git a/.gitignore b/.gitignore index 35e2d8f2e7..4742e13056 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,13 @@ mongo-test-output # core packages shouldn't have .versions files packages/*/.versions + +# packages shouldn't have .npm on Git +packages/**/.npm + +# doc files should not be committed +packages/**/*.docs.js + +#cursor +.cursorignore +.cursorrules diff --git a/.gitmodules b/.gitmodules index 17644a42a4..59b70023f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "packages/non-core/blaze"] path = packages/non-core/blaze - url = https://github.com/meteor/blaze.git \ No newline at end of file + url = https://github.com/meteor/blaze.git +[submodule "npm-packages/cordova-plugin-meteor-webapp/src/ios/GCDWebServer"] + path = npm-packages/cordova-plugin-meteor-webapp/src/ios/GCDWebServer + url = https://github.com/meteor/GCDWebServer.git + branch = master diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..711f4c4f56 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "esversion": 11 +} diff --git a/.travis.yml b/.travis.yml index 35e4e9f859..3e63726f4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,10 @@ language: node_js os: linux -dist: xenial +dist: jammy +sudo: required +services: xvfb node_js: - - "14.17.6" + - "22.17.0" cache: directories: - ".meteor" @@ -11,17 +13,22 @@ script: - travis_retry ./packages/test-in-console/run.sh env: global: - - CXX=g++-4.8 + - CXX=g++-12 - phantom=false - PUPPETEER_DOWNLOAD_PATH=~/.npm/chromium - jobs: - # We don't want to run the tests without fibers anymore. - # - DISABLE_FIBERS=1 - # Use a different flag, since node would use false as a string. - - FIBERS_ENABLED=1 + - TEST_PACKAGES_EXCLUDE=stylus + - METEOR_MODERN=true addons: apt: sources: - ubuntu-toolchain-r-test packages: - - g++-4.8 + - g++-12 + - libnss3 + +before_install: + - cat /etc/apt/sources.list + - python3 --version + - echo "deb http://archive.ubuntu.com/ubuntu jammy main universe" | sudo tee -a /etc/apt/sources.list + - sudo apt-get update + - sudo apt-get install -y libnss3 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 0c727908c2..fa910d2ee5 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,18 +8,18 @@ All recipients of reports commit to maintain the confidentiality with regard to ## Report an issue -To report an issue in one of the projects listed below, please send an email to code-of-conduct@meteor.com. +To report an issue in one of the projects listed below, please email code-of-conduct@meteor.com. * [OSS Meteor Projects](https://github.com/meteor) * [Meteor Forum](https://forums.meteor.com/) +* [Meteor Lounge on Discord](https://discord.gg/hZkTCaVjmT) ## Code of Conduct panel The Code of Conduct panel is a moderation team that handle code of conduct issues. The makeup of this team is as follows: * CEO at Meteor Software - Frederico Maia Arantes -* DevRel Manager at Meteor Software - Tatiana Barros -* Software Engineer at Meteor Software - Denilson Silva +* CTO at Meteor Software - Henrique Albert * CEO at High Impact Tech - Alim S. Gafar Members of the CoCP team will be added for a 1-year term and will be re-confirmed on a yearly basis. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e27d3b550..c646fad457 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ There are many ways to contribute to the Meteor Project. Hereβs a list of tech There are also several ways to contribute to the Meteor Project outside of GitHub, like organizing or speaking at [Meetups](https://forums.meteor.com/c/meetups) and events and helping to moderate our [forums](https://forums.meteor.com/). -If you can think of any changes to the project, [documentation](https://github.com/meteor/meteor/tree/devel/docs), or [guide](https://github.com/meteor/meteor/tree/devel/guide) that would improve the contributor experience, let us know by opening an issue! +If you can think of any changes to the project, [documentation](https://github.com/meteor/meteor/tree/devel/v3-docs), or [guide](https://github.com/meteor/meteor/tree/devel/guide) that would improve the contributor experience, let us know by opening an issue! ### Finding work @@ -43,15 +43,14 @@ Reviewers are members of the community who help with Pull Requests reviews. Current Reviewers: - [meteor](https://github.com/meteor/meteor) - - [@denihs](https://github.com/denihs) - [@fredmaiaarantes](https://github.com/fredmaiaarantes) - [@henriquealbert](https://github.com/henriquealbert) - [@aquinoit](https://github.com/aquinoit) - [@Grubba27](https://github.com/Grubba27) -- [@filipenevola](https://github.com/filipenevola) + - [@italojs](https://github.com/italojs) + - [@nachocodoner](https://github.com/nachocodoner) - [@StorytellerCZ](https://github.com/StorytellerCZ) - [@zodern](https://github.com/zodern) -- [@CaptainN](https://github.com/CaptainN) - [@radekmie](https://github.com/radekmie) #### Core Committer @@ -59,20 +58,19 @@ Current Reviewers: The contributors with commit access to meteor/meteor are employees of Meteor Software LP or community members who have distinguished themselves in other contribution areas or members of partner companies. If you want to become a core committer, please start writing PRs. Current Core Team: -- [@denihs](https://github.com/denihs) -- [@zodern](https://github.com/zodern) -- [@filipenevola](https://github.com/filipenevola) -- [@fredmaiaarantes](https://github.com/fredmaiaarantes) -- [@henriquealbert](https://github.com/henriquealbert) -- [@Grubba27](https://github.com/Grubba27) +- [meteor](https://github.com/meteor/meteor) + - [@fredmaiaarantes](https://github.com/fredmaiaarantes) + - [@henriquealbert](https://github.com/henriquealbert) + - [@Grubba27](https://github.com/Grubba27) + - [@italojs](https://github.com/italojs) + - [@nachocodoner](https://github.com/nachocodoner) - [@StorytellerCZ](https://github.com/StorytellerCZ) -- [@CaptainN](https://github.com/CaptainN) +- [@zodern](https://github.com/zodern) - [@radekmie](https://github.com/radekmie) -- [@matheusccastroo](https://github.com/matheusccastroo) ### Tracking project work -Right now, the best place to track the work being done on Meteor is to take a look at the latest release milestone [here](https://github.com/meteor/meteor/milestones). Also, the [Meteor Roadmap](https://docs.meteor.com/roadmap.html) contains high-level information on the current priorities of the project. +Right now, the best place to track the work being done on Meteor is to take a look at the latest release milestone [here](https://github.com/meteor/meteor/milestones). Also, the [Meteor Roadmap](https://docs.meteor.com/about/roadmap.html) contains high-level information on the current priorities of the project. ## Reporting a bug in Meteor @@ -134,7 +132,7 @@ for more details on proposing changes to core code. Feature requests are tracked in the [Discussions](https://github.com/meteor/meteor/discussions). Meteor is a big project with [many sub-projects](https://github.com/meteor/meteor/tree/devel/packages). -Community is welcome to help in all the sub-projects. We use our [roadmap](https://docs.meteor.com/roadmap.html) to communicate the high-level features we're currently prioritizing. +Community is welcome to help in all the sub-projects. We use our [roadmap](https://docs.meteor.com/about/roadmap.html) to communicate the high-level features we're currently prioritizing. Every additional feature adds a maintenance cost in addition to its value. This cost starts with the work of writing the feature or reviewing a community pull @@ -157,7 +155,7 @@ Learn how we use GitHub labels [here](LABELS.md) ## Documentation -If you'd like to contribute to Meteor's documentation, head over to https://docs.meteor.com or https://guide.meteor.com and if you find something that could be better click in "Edit on GitHub" footer to edit and submit a PR. +If you'd like to contribute to Meteor's documentation, head over to https://docs.meteor.com/about/contributing.html for guidelines. ## Blaze @@ -207,7 +205,7 @@ For more information about how to work with Meteor core, take a look at the [Dev ### Proposing your change -You'll have the best chance of getting a change into core if you can build consensus in the community for it or if it is listed in the [roadmap](https://docs.meteor.com/roadmap.html). Start by creating a well specified Discussion [here](https://github.com/meteor/meteor/discussions). +You'll have the best chance of getting a change into core if you can build consensus in the community for it or if it is listed in the [roadmap](https://docs.meteor.com/about/roadmap.html). Start by creating a well specified Discussion [here](https://github.com/meteor/meteor/discussions). Help drive discussion and advocate for your feature on the Github ticket (and perhaps the forums). The higher the demand for the feature and the greater the clarity of it's specification will determine the likelihood of a core contributor prioritizing your feature by flagging it with the `ready` label. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index dbbdfefcdd..a34dd51841 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -43,13 +43,19 @@ can run Meteor directly from a Git checkout using these steps: $ /path/to/meteor-checkout/meteor run ``` - > _Tip:_ Consider making an easy-to-run alias for frequent use: + > _Tip 1:_ Consider making an easy-to-run alias for frequent use: > > alias mymeteor=/path/to-meteor-checkout/meteor > > This allows the use of `mymeteor` in place of `meteor`. To persist this > across shell logouts, simply add it to `~/.bashrc` or `.zshrc`. + > _Tip 2:_ When working with meteor tool, it may be helpful to use the debugger to check what's happening. You can do this using the following flag: + > + > TOOL_NODE_FLAGS="--inspect-brk" mymeteor + > + > Then you can use the chrome debugger inside `chrome://inspect`. + ### Notes when running from a checkout The following are some distinct differences you must pay attention to when running Meteor from a checkout: diff --git a/History.md b/History.md index 91b0003589..7b252eed31 100644 --- a/History.md +++ b/History.md @@ -2,4 +2,4 @@ This content was moved to [history.md](./docs/history.md). -Previously the changelog was available to be edited here but it was always published in [https://docs.meteor.com/changelog.html](https://docs.meteor.com/changelog.html). +Previously the changelog was available to be edited here but it was always published in [https://docs.meteor.com/history.html](https://docs.meteor.com/history.html). diff --git a/README.md b/README.md index 16f6d2fc29..11aa1c4c6c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,21 @@
-