Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 119 additions & 58 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
name: Build
on: [push, pull_request]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read
id-token: write
packages: write

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
node_version:
- 24
name: Node ${{ matrix.node_version }} on ${{ matrix.os }}
version:
name: Determine build version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Build Reason
persist-credentials: false
- name: Setup .NET SDK for MinVer
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: "10.0.x"
- name: Build Version
id: version
shell: bash
run: |
branch=${GITHUB_REF##*/}.
Expand All @@ -36,68 +38,127 @@ jobs:
elif [[ "${GITHUB_REF}" = refs/pull* ]]; then
branch=""
fi
echo "GIT_BRANCH_SUFFIX=$branch" >> $GITHUB_ENV
echo "ref: $GITHUB_REF event: $GITHUB_EVENT_NAME branch_suffix: $branch"
- name: Setup Node.js environment
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node_version }}
registry-url: "https://registry.npmjs.org"
- name: Cache node_modules
uses: actions/cache@v5
with:
path: node_modules
key: ${{ matrix.node_version }}-${{ runner.os }}-node-modules-${{ hashFiles('package-lock.json') }}
- name: Setup .NET SDK for MinVer
uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- name: Build Version
id: version
shell: bash
run: |

dotnet tool install --global minver-cli --version 7.0.0
version=$(minver --tag-prefix v --default-pre-release-identifiers "preview.${GIT_BRANCH_SUFFIX}0" --minimum-major-minor 3.0)
version=$(minver --tag-prefix v --default-pre-release-identifiers "preview.${branch}0" --minimum-major-minor 3.0)

# If on a non-main branch, insert branch name before the height (last numeric segment)
if [ -n "$GIT_BRANCH_SUFFIX" ]; then
branch_name="${GIT_BRANCH_SUFFIX%.}"
if [ -n "$branch" ]; then
branch_name="${branch%.}"
if [[ "$version" != *"$branch_name"* ]]; then
version=$(echo "$version" | sed -E "s/\.([0-9]+)$/.${GIT_BRANCH_SUFFIX}\1/")
version=$(echo "$version" | sed -E "s/\.([0-9]+)$/.${branch}\1/")
fi
fi

echo "version=$version" >> $GITHUB_OUTPUT
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Version: $version"
echo "### Version: $version" >> $GITHUB_STEP_SUMMARY
echo "### Version: $version" >> "$GITHUB_STEP_SUMMARY"

npm install --global replace-in-files-cli
replace-in-files --string="3.0.0-dev" --replacement=$version packages/core/src/configuration/Configuration.ts
replace-in-files --string="3.0.0-dev" --replacement=$version **/package*.json
npm ci
build:
needs: version
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
node_version:
- 24
name: Node ${{ matrix.node_version }} on ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup Node.js environment
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ matrix.node_version }}
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: package-lock.json
- name: Apply Build Version
env:
BUILD_VERSION: ${{ needs.version.outputs.version }}
run: node scripts/set-build-version.mjs
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Lint
run: npm run lint
- name: Run Tests
run: npm test

publish-release:
name: Publish npm release
if: startsWith(github.ref, 'refs/tags/v')
needs: [version, build]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for npm trusted publishing.
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup Node.js environment
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: package-lock.json
- name: Apply Build Version
env:
BUILD_VERSION: ${{ needs.version.outputs.version }}
run: node scripts/set-build-version.mjs
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Publish Release Packages
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'ubuntu-latest'
run: npm publish --workspaces --access public
- name: Setup GitHub CI Node.js environment
if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/heads/') && matrix.os == 'ubuntu-latest' && contains(steps.version.outputs.version, '-')
uses: actions/setup-node@v6

publish-github:
name: Publish GitHub CI packages
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/') && contains(needs.version.outputs.version, '-')
needs: [version, build]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # Required to publish with GITHUB_TOKEN.
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
node-version: ${{ matrix.node_version }}
persist-credentials: false
- name: Setup Node.js environment
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: package-lock.json
- name: Apply Build Version
env:
BUILD_VERSION: ${{ needs.version.outputs.version }}
run: node scripts/set-build-version.mjs
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Setup GitHub Packages registry
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
registry-url: "https://npm.pkg.github.com"
scope: "@exceptionless"
- name: Push GitHub CI Packages
if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/heads/') && matrix.os == 'ubuntu-latest' && contains(steps.version.outputs.version, '-')
shell: bash
run: |
TAG_BRANCH="${GIT_BRANCH_SUFFIX%.}"
TAG_BRANCH="${TAG_BRANCH:-main}"
TAG_BRANCH="${TAG_BRANCH//\//-}"
npm publish --workspaces --access public --tag "ci-${TAG_BRANCH}" || true
run: | # zizmor: ignore[use-trusted-publishing] GitHub Packages uses GITHUB_TOKEN.
TAG_BRANCH="${GITHUB_REF##*/}"
npm publish --workspaces --access public --tag "ci-${TAG_BRANCH}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make branch package publishing idempotent

When this branch workflow is rerun for a commit whose packages were already published—especially after a partial publish—the deterministic MinVer output gives every workspace the same version again. The npm publish documentation states that publishing fails when the name/version combination already exists, so removing the previous error handling makes such reruns finish unsuccessfully even if only one workspace conflicts. Handle already-published versions explicitly while still surfacing genuine registry failures.

Useful? React with 👍 / 👎.

env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
legacy-peer-deps=true
min-release-age=7
# Security fixes for GHSA-w2rr-34g9-rvrj, GHSA-4w3w-2rp5-g8jm, and GHSA-g53g-w8rj-fmg7.
min-release-age-exclude[]=@xmldom/xmldom
11 changes: 11 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ export default defineConfig(
"@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }]
}
},
{
files: ["scripts/**/*.mjs"],
...tseslint.configs.disableTypeChecked,
languageOptions: {
...tseslint.configs.disableTypeChecked.languageOptions,
globals: {
console: "readonly",
process: "readonly"
}
}
},
eslintConfigPrettier,
{
files: ["**/test/**/*.ts"],
Expand Down
2 changes: 1 addition & 1 deletion example/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h1>Error Submission</h1>
<button onclick="throwReferenceError('function-does-exist')">Throw uncaught reference error</button>
<button id="throw-jquery-ajax-error">Throw jQuery ajax error</button>
<button id="throw-promise-unhandled-rejection">Throw promise unhandled rejection</button>
<button id="throw-browser-extension-error">Throw brower extension error</button>
<button id="throw-browser-extension-error">Throw browser extension error</button>

<h1>Log Submission</h1>
<button class="submit-log">Submit log event</button>
Expand Down
2 changes: 1 addition & 1 deletion example/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"access": "restricted"
},
"devDependencies": {
"vite": "^8.0.16"
"vite": "^8.2.0"
},
"dependencies": {
"@exceptionless/browser": "3.0.0-dev",
Expand Down
4 changes: 2 additions & 2 deletions example/browser/text-area-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class TextAreaLogger {
} else {
document.addEventListener("DOMContentLoaded", () => {
this.element = document.getElementById(elementId);
this.element.innerHTML = this.messageBuffer.join("\n") + this.element.innerHTML;
this.element.value = this.messageBuffer.join("\n") + this.element.value;
this.messageBuffer = [];
});
}
Expand All @@ -37,7 +37,7 @@ export class TextAreaLogger {
log(level, message) {
const formattedMessage = `${new Date().toISOString()} [${level}] ${message}`;
if (this.element) {
this.element.innerHTML += `\n${formattedMessage}`;
this.element.value += `\n${formattedMessage}`;
} else {
this.messageBuffer.push(formattedMessage);
}
Expand Down
2 changes: 1 addition & 1 deletion example/expo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function TopDiagnostics() {
<View style={styles.diagnostics}>
<View style={styles.diagnosticsTitleRow}>
<Text style={styles.diagnosticsTitle}>Exceptionless Expo</Text>
<Text style={styles.diagnosticsPill}>SDK 56</Text>
<Text style={styles.diagnosticsPill}>SDK 57</Text>
</View>
<Text style={styles.diagnosticsServer} numberOfLines={1}>
{serverUrl}
Expand Down
2 changes: 1 addition & 1 deletion example/expo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This example exercises `@exceptionless/react-native` from an Expo app. It covers

Native iOS crash reporting uses the package's custom native module, so it requires an Expo development build or a standalone app. Expo Go can run JavaScript reporting paths only; it cannot load the native crash reporter.

This app tracks Expo SDK 56.
This app tracks Expo SDK 57.

## Prerequisites

Expand Down
5 changes: 0 additions & 5 deletions example/expo/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
"icon": "./assets/icon.png",
"scheme": "exceptionless-expo",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.exceptionless.expo.example",
Expand Down
27 changes: 13 additions & 14 deletions example/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,25 @@
},
"dependencies": {
"@exceptionless/react-native": "3.0.0-dev",
"@expo/metro-runtime": "~56.0.15",
"@expo/metro-runtime": "~57.0.8",
"@react-native-async-storage/async-storage": "2.2.0",
"expo": "~56.0.11",
"expo-application": "~56.0.3",
"expo-constants": "~56.0.16",
"expo-dev-client": "~56.0.20",
"expo-device": "~56.0.4",
"expo-splash-screen": "~56.0.10",
"expo-status-bar": "~56.0.4",
"expo": "~57.0.10",
"expo-application": "~57.0.2",
"expo-constants": "~57.0.9",
"expo-dev-client": "~57.0.10",
"expo-device": "~57.0.1",
"expo-splash-screen": "~57.0.5",
"expo-status-bar": "~57.0.1",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-native": "0.85.3",
"react-native": "0.86.2",
"react-native-safe-area-context": "~5.7.0",
"react-native-screens": "4.25.2",
"react-native-web": "^0.21.0"
"react-native-screens": "~4.26.2",
"react-native-web": "^0.21.2"
},
"devDependencies": {
"@babel/core": "^7.29.7",
"@react-native/js-polyfills": "^0.79.6",
"@types/react": "~19.2.10",
"@react-native/js-polyfills": "^0.86.2",
"@types/react": "~19.2.18",
"typescript": "~6.0.3"
},
"publishConfig": {
Expand Down
9 changes: 9 additions & 0 deletions example/nextjs/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions example/nextjs/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
2 changes: 1 addition & 1 deletion example/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dependencies": {
"@exceptionless/browser": "3.0.0-dev",
"@exceptionless/node": "3.0.0-dev",
"next": "^16.2.7",
"next": "^16.3.0",
"react": "19.2.3",
"react-dom": "19.2.3"
},
Expand Down
7 changes: 4 additions & 3 deletions example/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
]
},
"devDependencies": {
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@vitejs/plugin-react": "^6.0.2",
"vite": "^8.0.16"
"@testing-library/user-event": "^14.6.3",
"@vitejs/plugin-react": "^6.0.5",
"vite": "^8.2.0"
},
"dependencies": {
"@exceptionless/react": "3.0.0-dev",
Expand Down
Loading