Skip to content
Merged
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
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ jobs:
with:
fail_ci_if_error: false

cli-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup Node.js and install dependencies
uses: ./.github/actions/setup-node-and-install

- name: Run CLI tests
run: yarn test-cli

build-prod:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ webpack.local-config.js
*.orig
*.rej
.idea/
.profiler-cli-dev/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
src/profile-logic/import/proto
src/types/libdef/npm
profiler-cli/dist
docs-user/js
docs-user/css
src/test/fixtures/upgrades
Expand Down
1 change: 1 addition & 0 deletions bin/output-fixing-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const fixingCommands = {
'lint-css': 'lint-fix-css',
'prettier-run': 'prettier-fix',
test: 'test -u',
'test-cli': 'test-cli -u',
};

const command = process.argv.slice(2);
Expand Down
58 changes: 58 additions & 0 deletions docs-developer/deploying.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,61 @@ To deploy on nginx (without support for direct upload from the Firefox UI), run
and point nginx at the `dist` directory, which needs to be at the root of the webserver. Additionally,
a `error_page 404 =200 /index.html;` directive needs to be added so that unknown URLs respond with index.html.
For a more production-ready configuration, have a look at the netlify [`_headers`](/res/_headers) file.

# Publishing profiler-cli to npm

The [`@firefox-devtools/profiler-cli`](https://www.npmjs.com/package/@firefox-devtools/profiler-cli)
package is published to npm from this repository. It provides a command-line
interface for querying Firefox Profiler profiles — see
[`profiler-cli/README.md`](../profiler-cli/README.md) for usage.

## Prerequisites

- Be logged in to npm (`npm login`) with publish access to the `@firefox-devtools` scope.
- Make sure the working tree is clean and you are on the commit you want to publish.
- Run `yarn test-all` (or at least `yarn test-cli`) to confirm the CLI still builds and passes tests.

## Bump the version

Edit the `version` field in [`profiler-cli/package.json`](../profiler-cli/package.json),
then land the version bump on `main` before publishing.

## Publish

From the repository root:

```
yarn publish-profiler-cli
```

[`scripts/publish-profiler-cli.mjs`](../scripts/publish-profiler-cli.mjs) will:

1. Run `yarn build-profiler-cli` to produce `profiler-cli/dist/profiler-cli.js` (a
single self-contained bundle with no runtime dependencies).
2. Run `npm publish profiler-cli/`, picking `--tag alpha` when the version
contains `-` (e.g. `0.1.0-alpha.5`) and `--tag latest` otherwise.
3. Trigger the `prepublishOnly` hook in `profiler-cli/package.json`, which runs
[`scripts/verify-profiler-cli-build.mjs`](../scripts/verify-profiler-cli-build.mjs)
to confirm the bundle exists and embeds the current `package.json` version —
this guards against publishing a stale build.

Extra arguments are forwarded to `npm publish`. For example:

```
# Build and verify, but do not actually publish.
yarn publish-profiler-cli --dry-run

# Override the automatic dist-tag.
yarn publish-profiler-cli --tag alpha
```

## Verify the release

After publishing, confirm the new version is listed on
[npm](https://www.npmjs.com/package/@firefox-devtools/profiler-cli) and installs
cleanly:

```
npm install -g @firefox-devtools/profiler-cli@latest
profiler-cli --version
```
3 changes: 2 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig(
ignores: [
'src/profile-logic/import/proto/**',
'src/types/libdef/npm/**',
'profiler-cli/dist/**',
'res/**',
'dist/**',
'node-tools-dist/**',
Expand Down Expand Up @@ -253,7 +254,7 @@ export default defineConfig(

// Test files override
{
files: ['src/test/**/*'],
files: ['src/test/**/*', 'profiler-cli/src/test/**/*'],
languageOptions: {
globals: {
...globals.jest,
Expand Down
77 changes: 63 additions & 14 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

module.exports = {
testMatch: ['<rootDir>/src/**/*.test.{js,jsx,ts,tsx}'],
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],

// Use custom resolver that respects the "browser" field in package.json
resolver: './jest-resolver.js',

// Shared config for projects that need a browser-like (jsdom) environment.
// CLI unit tests use the same environment because they import browser-side
// fixtures to construct profile data.
const browserEnvConfig = {
testEnvironment: './src/test/custom-environment',
setupFilesAfterEnv: ['jest-extended/all', './src/test/setup.ts'],

collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!**/node_modules/**',
'!src/types/libdef/**',
],
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
resolver: './jest-resolver.js',

transform: {
'\\.([jt]sx?|mjs)$': 'babel-jest',
Expand All @@ -43,5 +36,61 @@ module.exports = {
escapeString: true,
printBasicPrototype: true,
},
verbose: false,
};

const allProjects = [
// ========================================================================
// Browser Tests (React/browser environment)
// ========================================================================
{
...browserEnvConfig,
displayName: 'browser',
testMatch: ['<rootDir>/src/**/*.test.{js,jsx,ts,tsx}'],

collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!**/node_modules/**',
'!src/types/libdef/**',
],
},

// ========================================================================
// CLI Unit Tests (browser/jsdom environment - imports browser-side fixtures)
// ========================================================================
{
...browserEnvConfig,
displayName: 'cli',
testMatch: ['<rootDir>/profiler-cli/src/test/unit/**/*.test.ts'],
},

// ========================================================================
// CLI Integration Tests (Node.js environment - spawns real processes)
// ========================================================================
{
displayName: 'cli-integration',
testMatch: ['<rootDir>/profiler-cli/src/test/integration/**/*.test.ts'],

testEnvironment: 'node',

setupFilesAfterEnv: ['./profiler-cli/src/test/integration/setup.ts'],

// Integration tests can be slow (loading profiles, spawning processes)
testTimeout: 30000,

moduleFileExtensions: ['ts', 'js'],

transform: {
'\\.([jt]sx?|mjs)$': 'babel-jest',
},
},
];

// Filter projects by JEST_PROJECTS env var (comma-separated displayNames).
// Preferred over --selectProjects because that CLI flag is variadic and
// swallows positional args like `yarn test process-profile.ts`.
const filter = process.env.JEST_PROJECTS;
module.exports = {
projects: filter
? allProjects.filter((p) => filter.split(',').includes(p.displayName))
: allProjects,
};
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"build-sw": "workbox generateSW workbox-config.js",
"build-prod:quiet": "yarn build-prod",
"build-node-tools": "cross-env NODE_ENV=production node scripts/build-node-tools.mjs",
"build-profile-query": "cross-env NODE_ENV=production node scripts/build-profile-query.mjs",
"build-profile-query:quiet": "yarn build-profile-query",
"build-profiler-cli": "cross-env NODE_ENV=production node scripts/build-profiler-cli.mjs",
"build-profiler-cli:quiet": "yarn build-profiler-cli",
"publish-profiler-cli": "node scripts/publish-profiler-cli.mjs",
"lint": "node bin/output-fixing-commands.js run-p lint-js lint-css prettier-run",
"lint-fix": "run-p lint-fix-js lint-fix-css prettier-fix",
"lint-js": "node bin/output-fixing-commands.js eslint . --report-unused-disable-directives --cache --cache-strategy content",
Expand All @@ -42,15 +47,16 @@
"start-examples": "ws -d examples/ -s index.html -p 4244",
"start-docs": "ws -d docs-user/ -p 3000",
"start-photon": "node scripts/run-photon-dev-server.mjs",
"test": "node bin/output-fixing-commands.js cross-env LC_ALL=C TZ=UTC NODE_ENV=test jest",
"test": "node bin/output-fixing-commands.js cross-env LC_ALL=C TZ=UTC NODE_ENV=test JEST_PROJECTS=browser jest",
"test-node": "node bin/output-fixing-commands.js cross-env LC_ALL=C TZ=UTC NODE_ENV=test JEST_ENVIRONMENT=node jest",
"test-all": "run-p --max-parallel 4 ts license-check lint test test-alex test-lockfile",
"test-all": "run-p --max-parallel 4 ts license-check lint test test-alex test-lockfile && yarn test-cli",
"test-build-coverage": "yarn test --coverage --coverageReporters=html",
"test-serve-coverage": "ws -d coverage/ -p 4343",
"test-coverage": "run-s test-build-coverage test-serve-coverage",
"test-alex": "alex ./docs-* CODE_OF_CONDUCT.md CONTRIBUTING.md README.md",
"test-lockfile": "lockfile-lint --path yarn.lock --allowed-hosts yarn --validate-https",
"test-debug": "cross-env LC_ALL=C TZ=UTC NODE_ENV=test node --inspect-brk node_modules/.bin/jest --runInBand",
"test-cli": "yarn build-profiler-cli && node bin/output-fixing-commands.js cross-env LC_ALL=C TZ=UTC NODE_ENV=test JEST_PROJECTS=cli,cli-integration jest",
"postinstall": "patch-package"
},
"license": "MPL-2.0",
Expand All @@ -75,6 +81,7 @@
"array-range": "^1.0.1",
"clamp": "^1.0.1",
"classnames": "^2.5.1",
"commander": "^14.0.3",
"common-tags": "^1.8.2",
"copy-to-clipboard": "^4.0.2",
"core-js": "^3.49.0",
Expand Down
Loading
Loading