mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'oxc/phase-1' into oxc/phase-2
This commit is contained in:
53
.github/workflows/test-packages.yml
vendored
Normal file
53
.github/workflows/test-packages.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Test Packages
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "packages/**"
|
||||
- ".github/workflows/test-packages.yml"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-packages:
|
||||
runs-on: oss-vm
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CXX: g++-12
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Expose globally-installed puppeteer to Node.js
|
||||
# puppeteer@23.6.0 is pre-installed on oss-vm via `npm install -g`.
|
||||
# Setting NODE_PATH lets `require('puppeteer')` resolve it directly,
|
||||
# so run.sh skips the slow `./meteor npm install -g puppeteer` step.
|
||||
run: echo "NODE_PATH=$(npm root -g)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Restore caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.npm
|
||||
.meteor
|
||||
.babel-cache
|
||||
dev_bundle
|
||||
key: ${{ runner.os }}-meteor-${{ hashFiles('meteor', '**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-meteor-
|
||||
|
||||
- name: Run test-in-console suite
|
||||
run: |
|
||||
export TEST_PACKAGES_EXCLUDE="stylus"
|
||||
export METEOR_MODERN="true"
|
||||
export NODE_ENV="CI"
|
||||
export CXX="g++-12"
|
||||
export phantom="false"
|
||||
export TIMEOUT_SCALE_FACTOR="20"
|
||||
export METEOR_HEADLESS="true"
|
||||
./packages/test-in-console/run.sh
|
||||
14
.github/workflows/type-coverage.yml
vendored
Normal file
14
.github/workflows/type-coverage.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Type Coverage
|
||||
on:
|
||||
- pull_request
|
||||
jobs:
|
||||
type-coverage:
|
||||
runs-on: oss-vm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- run: npm ci
|
||||
- name: Check TypeScript type coverage (80%)
|
||||
run: npm run ts-coverage:ci
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -36,6 +36,9 @@ packages/**/.npm
|
||||
# doc files should not be committed
|
||||
packages/**/*.docs.js
|
||||
|
||||
# coverage
|
||||
coverage-ts/
|
||||
|
||||
#cursor
|
||||
.cursorignore
|
||||
.cursorrules
|
||||
|
||||
1302
package-lock.json
generated
1302
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -21,7 +21,9 @@
|
||||
"lefthook": "^2.1.4",
|
||||
"oxfmt": "^0.42.0",
|
||||
"oxlint": "^1.57.0",
|
||||
"typescript": "^5.4.5"
|
||||
"type-coverage": "^2.29.7",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript-coverage-report": "^1.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
"fmt": "oxfmt --ignore-path .fmtignore .",
|
||||
@@ -33,7 +35,9 @@
|
||||
"test:idle-bot": "node --test .github/scripts/__tests__/inactive-issues.test.js",
|
||||
"install:e2e": "cd tools/modern-tests && npm install && npx playwright install --with-deps chromium chromium-headless-shell",
|
||||
"test:e2e": "cd tools/modern-tests && npm test -- ",
|
||||
"checkout:pr": "node scripts/checkout-pr.js"
|
||||
"checkout:pr": "node scripts/checkout-pr.js",
|
||||
"ts-coverage": "typescript-coverage-report",
|
||||
"ts-coverage:ci": "type-coverage --at-least 80"
|
||||
},
|
||||
"jshintConfig": {
|
||||
"esversion": 11
|
||||
@@ -82,4 +86,4 @@
|
||||
"sort-imports": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,7 +304,7 @@ export class Sunburst {
|
||||
});
|
||||
}
|
||||
|
||||
// Update the breadcrumb trail to show the current sequence and percentage.
|
||||
// Update the breadcrumb trail to show the current sequence.
|
||||
updateBreadcrumbs(nodeArray) {
|
||||
// Data join; key function combines name and depth (= position in sequence).
|
||||
const trail = this.elements.trail
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
const puppeteer = require("../../dev_bundle/lib/node_modules/puppeteer");
|
||||
let puppeteer;
|
||||
try {
|
||||
// Prefer the copy bundled inside dev_bundle (local checkout / CI after first run).
|
||||
puppeteer = require("../../dev_bundle/lib/node_modules/puppeteer");
|
||||
} catch (_) {
|
||||
// Fallback: globally-installed puppeteer (e.g. on oss-vm where it is pre-installed
|
||||
// via `npm install -g puppeteer@23.6.0` and NODE_PATH is set to `npm root -g`).
|
||||
puppeteer = require("puppeteer");
|
||||
}
|
||||
|
||||
let testNumber = 0;
|
||||
|
||||
@@ -20,19 +28,23 @@ async function runNextUrl(browser) {
|
||||
else {
|
||||
testNumber++;
|
||||
const currentClientTest = await page.evaluate(() =>
|
||||
__Tinytest._getCurrentRunningTestOnClient(),
|
||||
__Tinytest._getCurrentRunningTestOnClient()
|
||||
);
|
||||
if (currentClientTest !== "") {
|
||||
console.log(`Currently running on the client test: ${currentClientTest}`);
|
||||
console.log(
|
||||
`Currently running on the client test: ${currentClientTest}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
// If we get here is because we have not yet started the test on the client
|
||||
const currentServerTest = await page.evaluate(
|
||||
async () => await __Tinytest._getCurrentRunningTestOnServer(),
|
||||
async () => await __Tinytest._getCurrentRunningTestOnServer()
|
||||
);
|
||||
|
||||
if (currentServerTest !== "") {
|
||||
console.log(`Currently running on the server test: ${currentServerTest}`);
|
||||
console.log(
|
||||
`Currently running on the server test: ${currentServerTest}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
// we were not able to find the name of the test, this is a way to make sure the test is still running
|
||||
@@ -45,7 +57,13 @@ async function runNextUrl(browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
await page.goto(process.env.URL);
|
||||
// Use domcontentloaded: Meteor apps connect via DDP after DOM parse and never
|
||||
// fire the default 'load' event in the traditional sense. Increase timeout to
|
||||
// 90 s to handle slow first-run builds on CI / underpowered machines.
|
||||
await page.goto(process.env.URL, {
|
||||
timeout: 90000,
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
|
||||
async function poll() {
|
||||
if (await isDone(page)) {
|
||||
@@ -135,7 +153,11 @@ async function runTests() {
|
||||
|
||||
// --no-sandbox and --disable-setuid-sandbox must be disabled for CI compatibility
|
||||
const browser = await puppeteer.launch({
|
||||
args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-web-security"],
|
||||
args: [
|
||||
"--no-sandbox",
|
||||
"--disable-setuid-sandbox",
|
||||
"--disable-web-security",
|
||||
],
|
||||
headless: "new",
|
||||
});
|
||||
console.log(`Using version: ${await browser.version()}`);
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
cd $(dirname $0)/../..
|
||||
export METEOR_HOME=`pwd`
|
||||
|
||||
# Installs into dev_bundle/lib/node_modules/puppeteer.
|
||||
./meteor npm install -g puppeteer@23.6.0
|
||||
# Install puppeteer into dev_bundle only when it is not already available globally
|
||||
# (e.g. on oss-vm, where puppeteer@23.6.0 is pre-installed via system npm and
|
||||
# NODE_PATH is set to $(npm root -g) by the CI workflow).
|
||||
if ! node -e "require('./dev_bundle/lib/node_modules/puppeteer')" 2>/dev/null && \
|
||||
! node -e "require('puppeteer')" 2>/dev/null; then
|
||||
./meteor npm install -g puppeteer@23.6.0
|
||||
fi
|
||||
|
||||
export PATH=$METEOR_HOME:$PATH
|
||||
|
||||
@@ -22,6 +27,15 @@ trap "pkill -TERM -P $EXEC_PID; exit 1" SIGINT
|
||||
|
||||
sed '/test-in-console listening$/q' <&3
|
||||
|
||||
# Wait until the HTTP server is actually accepting connections before launching
|
||||
# Puppeteer. 'test-in-console listening' is emitted by the test driver before
|
||||
# the HTTP port is fully bound, so a bare goto() would time out on slow starts.
|
||||
echo "Waiting for test server at $URL..."
|
||||
until curl --silent --output /dev/null --fail "$URL"; do
|
||||
sleep 1
|
||||
done
|
||||
echo "Test server is ready."
|
||||
|
||||
node --trace-warnings "$METEOR_HOME/packages/test-in-console/puppeteer_runner.js"
|
||||
|
||||
STATUS=$?
|
||||
|
||||
@@ -26,6 +26,32 @@ const isMacOS = () => {
|
||||
return platform() === 'darwin';
|
||||
};
|
||||
|
||||
// Resolve the current process's primary group name by looking up its GID in
|
||||
// /etc/group. This is used in tests that chown a socket file: we need a group
|
||||
// the running user actually belongs to, so the chown doesn't fail with EPERM.
|
||||
const getCurrentGroupName = () => {
|
||||
try {
|
||||
const gid = userInfo().gid;
|
||||
const lines = readFileSync('/etc/group', 'utf8').split('\n');
|
||||
const match = lines.find(line => parseInt(line.split(':')[2], 10) === gid);
|
||||
return match ? match.split(':')[0] : null;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getGroupToUse = () => {
|
||||
if (isMacOS()) {
|
||||
return 'staff';
|
||||
}
|
||||
|
||||
if (process.env.TRAVIS) {
|
||||
return 'travis';
|
||||
}
|
||||
|
||||
return getCurrentGroupName() || 'root';
|
||||
};
|
||||
|
||||
const removeTestSocketFile = () => {
|
||||
try {
|
||||
unlinkSync(testSocketFile);
|
||||
@@ -133,7 +159,7 @@ testAsyncMulti(
|
||||
// use UNIX_SOCKET_PATH and UNIX_SOCKET_GROUP
|
||||
const { httpServer, server } = prepareServer();
|
||||
|
||||
const groupToUse = Boolean(process.env.TRAVIS) && 'travis' || (isMacOS() ? 'staff' : 'root');
|
||||
const groupToUse = getGroupToUse();
|
||||
process.env.UNIX_SOCKET_PATH = testSocketFile;
|
||||
process.env.UNIX_SOCKET_GROUP = groupToUse;
|
||||
process.env.UNIX_SOCKET_PERMISSIONS = '777';
|
||||
|
||||
161
scripts/list_package_changes.sh
Normal file
161
scripts/list_package_changes.sh
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# list_package_changes.sh
|
||||
# Lists folders changed inside /package for every open PR
|
||||
#
|
||||
# Usage:
|
||||
# ./list_package_changes.sh [--output file.json] [--exclude-author author1,author2,...]
|
||||
#
|
||||
# Examples:
|
||||
# ./list_package_changes.sh
|
||||
# ./list_package_changes.sh --output packages_by_pr.json
|
||||
# ./list_package_changes.sh --exclude-author dependabot,renovate
|
||||
# ./list_package_changes.sh --output packages_by_pr.json --exclude-author dependabot
|
||||
#
|
||||
# Requirements:
|
||||
# - gh CLI installed and authenticated (gh auth login)
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
OUTPUT_FILE=""
|
||||
EXCLUDE_AUTHORS=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--output)
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--exclude-author)
|
||||
EXCLUDE_AUTHORS="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "❌ Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- Check gh CLI is available and authenticated ---
|
||||
if ! command -v gh &>/dev/null; then
|
||||
echo "❌ gh CLI not found. Install it at https://cli.github.com/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! gh auth status &>/dev/null 2>&1; then
|
||||
echo "❌ gh CLI is not authenticated. Run: gh auth login"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Detect owner/repo from git remote ---
|
||||
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || echo "")
|
||||
if [[ -z "$REPO" ]]; then
|
||||
echo "❌ Could not detect repository. Run this script inside a git repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 Repository: $REPO"
|
||||
echo "⬇️ Fetching open PRs..."
|
||||
|
||||
# --- Fetch all open PRs ---
|
||||
ALL_PRS=$(gh pr list \
|
||||
--repo "$REPO" \
|
||||
--state open \
|
||||
--limit 500 \
|
||||
--json number,title,headRefName,author,url)
|
||||
|
||||
TOTAL=$(echo "$ALL_PRS" | jq 'length')
|
||||
echo "✅ $TOTAL open PRs found"
|
||||
echo ""
|
||||
|
||||
# --- Loop through each PR ---
|
||||
RESULT="{}"
|
||||
FOUND_ANY=false
|
||||
|
||||
while IFS= read -r pr; do
|
||||
PR_NUM=$(echo "$pr" | jq -r '.number')
|
||||
PR_TITLE=$(echo "$pr" | jq -r '.title')
|
||||
PR_BRANCH=$(echo "$pr" | jq -r '.headRefName')
|
||||
PR_AUTHOR=$(echo "$pr" | jq -r '.author.login')
|
||||
PR_URL=$(echo "$pr" | jq -r '.url')
|
||||
|
||||
# Skip excluded authors
|
||||
if [[ -n "$EXCLUDE_AUTHORS" ]]; then
|
||||
IFS=',' read -ra EXCLUDED <<< "$EXCLUDE_AUTHORS"
|
||||
SKIP=false
|
||||
for excluded in "${EXCLUDED[@]}"; do
|
||||
if [[ "$PR_AUTHOR" == "$excluded" ]]; then
|
||||
SKIP=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$SKIP" == true ]]; then
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fetch changed files for this PR
|
||||
PR_FILES=$(gh pr view "$PR_NUM" \
|
||||
--repo "$REPO" \
|
||||
--json files \
|
||||
-q '.files[].path' 2>/dev/null || echo "")
|
||||
|
||||
if [[ -z "$PR_FILES" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Filter files inside /packages and extract immediate subfolder
|
||||
# e.g. packages/my-module/src/foo.ts → packages/my-module
|
||||
PACKAGES=$(echo "$PR_FILES" \
|
||||
| (grep -E '^packages/' || true) \
|
||||
| awk -F'/' '{print $1"/"$2}' \
|
||||
| sort -u)
|
||||
|
||||
if [[ -z "$PACKAGES" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
FOUND_ANY=true
|
||||
|
||||
# Print to terminal
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "PR #$PR_NUM — $PR_TITLE"
|
||||
echo "👤 $PR_AUTHOR | 🌿 $PR_BRANCH"
|
||||
echo "🔗 $PR_URL"
|
||||
echo "📁 Changed folders in /package:"
|
||||
while IFS= read -r pkg; do
|
||||
echo " • $pkg"
|
||||
done <<< "$PACKAGES"
|
||||
echo ""
|
||||
|
||||
# Accumulate JSON result — keyed by package name
|
||||
PR_ENTRY=$(jq -n \
|
||||
--argjson num "$PR_NUM" \
|
||||
--arg title "$PR_TITLE" \
|
||||
--arg branch "$PR_BRANCH" \
|
||||
--arg author "$PR_AUTHOR" \
|
||||
--arg url "$PR_URL" \
|
||||
'{pr: $num, title: $title, branch: $branch, author: $author, url: $url}')
|
||||
while IFS= read -r pkg; do
|
||||
RESULT=$(echo "$RESULT" | jq --arg pkg "$pkg" --argjson entry "$PR_ENTRY" \
|
||||
'if has($pkg) then .[$pkg] += [$entry] else . + {($pkg): [$entry]} end')
|
||||
done <<< "$PACKAGES"
|
||||
|
||||
done < <(echo "$ALL_PRS" | jq -c '.[]')
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
if [[ "$FOUND_ANY" == false ]]; then
|
||||
echo "ℹ️ No PRs found that change files inside /packages."
|
||||
else
|
||||
PKG_COUNT=$(echo "$RESULT" | jq 'keys | length')
|
||||
echo "📊 $PKG_COUNT package(s) touched across open PRs."
|
||||
fi
|
||||
|
||||
# --- Save JSON if requested ---
|
||||
if [[ -n "$OUTPUT_FILE" ]]; then
|
||||
echo "$RESULT" | jq '.' > "$OUTPUT_FILE"
|
||||
echo "💾 Results saved to: $OUTPUT_FILE"
|
||||
fi
|
||||
@@ -7,18 +7,26 @@
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"noEmit": true,
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"moduleResolution": "node",
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./types"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"types/**/*.d.ts"
|
||||
"packages/**/*.ts",
|
||||
"packages/**/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
"node_modules",
|
||||
"**/node_modules/**",
|
||||
"**/.npm/**",
|
||||
"tools/static-assets/skel*/**",
|
||||
"tools/static-assets/scaffolds*/**",
|
||||
"tools/tests/**",
|
||||
"tools/modern-tests/**"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
## v3.3.1, 05-08-2025
|
||||
## v3.3.1, 2025-08-05
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -113,4 +113,4 @@ If you find any issues, please report them to the [Meteor issues tracker](https:
|
||||
- [@welkinwong](https://github.com/welkinwong)
|
||||
- [@Saksham-Goel1107](https://github.com/Saksham-Goel1107)
|
||||
|
||||
✨✨✨
|
||||
✨✨✨
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## v3.3.2, 01-09-2025
|
||||
## v3.3.2, 2025-09-01
|
||||
|
||||
### Highlights
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## v3.4.0, 30-01-2026
|
||||
## v3.4.0, 2026-01-30
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -143,4 +143,4 @@ If you find any issues, please report them to the [Meteor issues tracker](https:
|
||||
- [@jeetburman](https://github.com/jeetburman)
|
||||
- [@copleykj](https://github.com/copleykj)
|
||||
|
||||
✨✨✨
|
||||
✨✨✨
|
||||
|
||||
@@ -8,7 +8,4 @@ This is a complete history of changes for Meteor releases.
|
||||
|
||||
[//]: # (If you want to change something in this file)
|
||||
|
||||
[//]: # (go to meteor/docs/generators/changelog/docs)
|
||||
|
||||
|
||||
|
||||
[//]: # (go to meteor/v3-docs/docs/generators/changelog/versions)
|
||||
|
||||
@@ -8,11 +8,8 @@ This is a complete history of changes for Meteor releases.
|
||||
|
||||
[//]: # (If you want to change something in this file)
|
||||
|
||||
[//]: # (go to meteor/docs/generators/changelog/docs)
|
||||
|
||||
|
||||
|
||||
## v3.4.0, 30-01-2026
|
||||
[//]: # (go to meteor/v3-docs/docs/generators/changelog/versions)
|
||||
## v3.4.0, 2026-01-30
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -157,8 +154,8 @@ If you find any issues, please report them to the [Meteor issues tracker](https:
|
||||
- [@jeetburman](https://github.com/jeetburman)
|
||||
- [@copleykj](https://github.com/copleykj)
|
||||
|
||||
✨✨✨
|
||||
## v3.3.2, 01-09-2025
|
||||
✨✨✨
|
||||
## v3.3.2, 2025-09-01
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -227,7 +224,7 @@ If you find any issues, please report them to the [Meteor issues tracker](https:
|
||||
- [@copleykj](https://github.com/copleykj)
|
||||
|
||||
✨✨✨
|
||||
## v3.3.1, 05-08-2025
|
||||
## v3.3.1, 2025-08-05
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -342,7 +339,7 @@ If you find any issues, please report them to the [Meteor issues tracker](https:
|
||||
- [@welkinwong](https://github.com/welkinwong)
|
||||
- [@Saksham-Goel1107](https://github.com/Saksham-Goel1107)
|
||||
|
||||
✨✨✨
|
||||
✨✨✨
|
||||
## v3.3.0, 2025-06-11
|
||||
|
||||
### Highlights
|
||||
|
||||
Reference in New Issue
Block a user