Merge branch 'oxc/phase-1' into oxc/phase-2

This commit is contained in:
Italo José
2026-04-10 10:54:49 -03:00
committed by GitHub
16 changed files with 1332 additions and 343 deletions

53
.github/workflows/test-packages.yml vendored Normal file
View 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
View 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
View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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"
}
}
}
}

View File

@@ -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

View File

@@ -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()}`);

View File

@@ -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=$?

View File

@@ -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';

View 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

View File

@@ -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/**"
]
}

View File

@@ -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)
✨✨✨
✨✨✨

View File

@@ -1,4 +1,4 @@
## v3.3.2, 01-09-2025
## v3.3.2, 2025-09-01
### Highlights

View File

@@ -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)
✨✨✨
✨✨✨

View File

@@ -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)

View File

@@ -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