From df8e1d979bcac695c2be6bdf320f24f16d42d608 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 4 Nov 2025 13:30:44 +0100 Subject: [PATCH 1/4] chore: Prepare to use TypeScript natively --- .github/workflows/build.yml | 3 +++ .gitignore | 1 + .npmignore | 2 +- bin/sentry-cli | 2 +- package.json | 10 ++++++---- scripts/install.js | 4 ++-- tsconfig.json | 7 ++++--- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 549cb102af..44abdcbb1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -228,6 +228,9 @@ jobs: with: node-version: '20.10.0' + - name: Install dependencies + run: npm ci --ignore-scripts + - name: Download compiled binaries uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # 6.0.0 with: diff --git a/.gitignore b/.gitignore index ddf709559d..e5fb9fbff4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ target node_modules coverage dist +js-dist dump checksums.txt yarn-error.log diff --git a/.npmignore b/.npmignore index b758a43b1d..332009cf15 100644 --- a/.npmignore +++ b/.npmignore @@ -6,7 +6,7 @@ !README.md !LICENSE !bin/sentry-cli -!js +!js-dist !scripts/install.js !checksums.txt diff --git a/bin/sentry-cli b/bin/sentry-cli index 81fb8c6f65..667d4d360c 100755 --- a/bin/sentry-cli +++ b/bin/sentry-cli @@ -3,7 +3,7 @@ 'use strict'; const childProcess = require('child_process'); -const SentryCli = require('../js'); +const SentryCli = require('../js-dist'); const child = childProcess .spawn(SentryCli.getPath(), process.argv.slice(2), { diff --git a/package.json b/package.json index 87b52dbce1..82f4e6a70c 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "engines": { "node": ">= 10" }, - "main": "js/index.js", - "types": "js/index.d.ts", + "main": "js-dist/index.js", + "types": "js-dist/index.d.ts", "bin": { "sentry-cli": "bin/sentry-cli" }, @@ -29,7 +29,7 @@ "jest": "^27.5.1", "npm-run-all": "^4.1.5", "prettier": "2.8.8", - "typescript": "~5.8.3" + "typescript": "5.8.3" }, "optionalDependencies": { "@sentry/cli-darwin": "2.58.2", @@ -42,7 +42,9 @@ "@sentry/cli-win32-arm64": "2.58.2" }, "scripts": { - "postinstall": "node ./scripts/install.js", + "postinstall": "npm run build && node ./scripts/install.js", + "build": "tsc", + "prepack": "npm run build", "fix": "npm-run-all fix:eslint fix:prettier", "fix:eslint": "eslint --fix bin/* scripts/**/*.js js/**/*.js", "fix:prettier": "prettier --write bin/* scripts/**/*.js js/**/*.js", diff --git a/scripts/install.js b/scripts/install.js index eb1fb94987..3324bcf260 100755 --- a/scripts/install.js +++ b/scripts/install.js @@ -16,9 +16,9 @@ const ProgressBar = require('progress'); const Proxy = require('proxy-from-env'); const which = require('which'); -const helper = require('../js/helper'); +const helper = require('../js-dist/helper'); const pkgInfo = require('../package.json'); -const Logger = require('../js/logger'); +const Logger = require('../js-dist/logger'); const logger = new Logger(getLogStream('stderr')); diff --git a/tsconfig.json b/tsconfig.json index 4091588619..0cf30654ec 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,12 +2,13 @@ "compilerOptions": { "allowJs": true, "checkJs": true, - "noEmit": true, "resolveJsonModule": true, "target": "ES2015", "moduleResolution": "node", - "skipLibCheck": true + "skipLibCheck": true, + "rootDir": "js", + "outDir": "js-dist" }, - "include": ["js/**/*.js"], + "include": ["js/**/*.ts", "js/**/*.js"], "exclude": ["**/__tests__/**", "**/__mocks__/**"] } From c50084dc68d1796fd405783746a22974588c03ca Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 4 Nov 2025 14:22:26 +0100 Subject: [PATCH 2/4] chore: Move types as they were before --- js/helper.js | 4 +- js/index.d.ts | 248 ------------------------------------------- js/index.js | 17 ++- js/releases/index.js | 45 ++++---- js/types.ts | 244 ++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 3 +- 6 files changed, 281 insertions(+), 280 deletions(-) delete mode 100644 js/index.d.ts create mode 100644 js/types.ts diff --git a/js/helper.js b/js/helper.js index ff23054c3e..19028a5ddb 100644 --- a/js/helper.js +++ b/js/helper.js @@ -288,8 +288,8 @@ function getPath() { * exits with a non-zero exit code. * @param {boolean} silent Disable stdout for silents build (CI/Webpack Stats, ...) * @param {string} [configFile] Relative or absolute path to the configuration file. - * @param {Object} [config] More configuration to pass to the CLI - * @returns {Promise.} A promise that resolves to the standard output. + * @param {import('./index').SentryCliOptions} [config] More configuration to pass to the CLI + * @returns {Promise} A promise that resolves to the standard output. */ async function execute(args, live, silent, configFile, config = {}) { const env = { ...process.env }; diff --git a/js/index.d.ts b/js/index.d.ts deleted file mode 100644 index e0d9f76d5a..0000000000 --- a/js/index.d.ts +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Typings for @sentry/cli - */ -declare module '@sentry/cli' { - export interface SentryCliOptions { - /** - * The URL of the Sentry instance you are connecting to. Defaults to https://sentry.io/. - * This value will update `SENTRY_URL env variable. - */ - url?: string; - /** - * Authentication token for HTTP requests to Sentry. - * This value will update `SENTRY_AUTH_TOKEN` env variable. - */ - authToken?: string; - /** - * API key to authenticate any HTTP requests to Sentry (legacy authentication method). - * This value will update `SENTRY_API_KEY` env variable. - * @deprecated Use auth-token-based authentication via `authToken` instead. - * This option is scheduled for removal in the next major release. - */ - apiKey?: string; - /** - * Sentry DSN. - * This value will update `SENTRY_DSN` env variable. - */ - dsn?: string; - /** - * Organization slug. - * This value will update `SENTRY_ORG` env variable. - */ - org?: string; - /** - * Project Project slug. - * This value will update `SENTRY_PROJECT` env variable. - */ - project?: string; - /** - * Version control system remote name. - * This value will update `SENTRY_VCS_REMOTE` env variable. - */ - vcsRemote?: string; - /** - * If true, all logs are suppressed. - */ - silent?: boolean; - /** - * A header added to every outgoing network request. - * This value will update `CUSTOM_HEADER` env variable. - */ - customHeader?: string; - /** - * Headers added to every outgoing network request. - * This value does not set any env variable, and is overridden by `customHeader`. - */ - headers?: Record; - } - - /** - * Custom upload-sourcemaps options for a particular `include` path. In this - * case `paths` takes the place of `include` in the options so as to make it - * clear that this is not recursive. - */ - export type SourceMapsPathDescriptor = Omit & { - paths: string[]; - }; - - export interface SentryCliUploadSourceMapsOptions { - /** - * One or more paths that Sentry CLI should scan recursively for sources. - * It will upload all .map files and match associated .js files. - */ - include: Array; - /** - * One or more paths to ignore during upload. Overrides entries in ignoreFile file. - */ - ignore?: string[]; - /** - * Path to a file containing list of files/directories to ignore. - * Can point to .gitignore or anything with same format. - */ - ignoreFile?: string | null; - /** - * Enables rewriting of matching sourcemaps so that indexed maps are flattened - * and missing sources are inlined if possible. Defaults to `true`. - */ - rewrite?: boolean; - /** - * This prevents the automatic detection of sourcemap references. - */ - sourceMapReference?: boolean; - /** - * Enables files gzip decompression prior to uploading. Defaults to `false`. - */ - decompress?: boolean; - /** - * Enable artifacts deduplication prior to uploading. This will skip uploading - * any artifacts that are already present on the server. Defaults to `true`. - */ - dedupe?: boolean; - /** - * When paired with the rewrite option this will remove a prefix from uploaded files. - * For instance you can use this to remove a path that is build machine specific. - */ - stripPrefix?: string[]; - /** - * When paired with the rewrite option this will add ~ to the stripPrefix array. - */ - stripCommonPrefix?: boolean; - /** - * The projects to upload the sourcemaps to. If not provided, the sourcemaps will be uploaded to the default project. - */ - projects?: string[]; - /** - * This attempts sourcemap validation before upload when rewriting is not enabled. - * It will spot a variety of issues with source maps and cancel the upload if any are found. - * This is not enabled by default as this can cause false positives. - */ - validate?: boolean; - /** - * This sets an URL prefix at the beginning of all files. - * This defaults to `~/` but you might want to set this to the full URL. - * This is also useful if your files are stored in a sub folder. eg: url-prefix `~/static/js`. - */ - urlPrefix?: string; - /** - * This sets an URL suffix at the end of all files. - * Useful for appending query parameters. - */ - urlSuffix?: string; - /** - * This sets the file extensions to be considered. - * By default the following file extensions are processed: js, map, jsbundle and bundle. - */ - ext?: string[]; - /** - * Unique identifier for the distribution, used to further segment your release. - * Usually your build number. - */ - dist?: string; - /** - * Force use of new Artifact Bundles upload, that enables use of Debug ID for Source Maps discovery, - * even when the Sentry server does not declare support for it. - * - * @deprecated This option is deprecated and will be removed in the next major version. Sentry CLI - * should always respect what the server says it supports. - */ - useArtifactBundle?: boolean; - } - - export interface SentryCliNewDeployOptions { - /** - * Environment for this release. Values that make sense here would be `production` or `staging`. - */ - env: string; - /** - * Deployment start time in Unix timestamp (in seconds) or ISO 8601 format. - */ - started?: number | string; - /** - * Deployment finish time in Unix timestamp (in seconds) or ISO 8601 format. - */ - finished?: number | string; - /** - * Deployment duration (in seconds). Can be used instead of started and finished. - */ - time?: number; - /** - * Human readable name for the deployment. - */ - name?: string; - /** - * URL that points to the deployment. - */ - url?: string; - } - - export interface SentryCliCommitsOptions { - /** - * Automatically choose the associated commit (uses the current commit). Overrides other setCommit options. - */ - auto?: boolean; - /** - * The full repo name as defined in Sentry. Required if auto option is not true. - */ - repo?: string; - /** - * The current (last) commit in the release. Required if auto option is not true. - */ - commit?: string; - /** - * The commit before the beginning of this release (in other words, the last commit of the previous release). - * If omitted, this will default to the last commit of the previous release in Sentry. - * If there was no previous release, the last 10 commits will be used. - */ - previousCommit?: string; - /** - * When the flag is set and the previous release commit was not found in the repository, will create a release - * with the default commits count(or the one specified with `--initial-depth`) instead of failing the command. - */ - ignoreMissing?: boolean; - /** - * When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found. - */ - ignoreEmpty?: boolean; - } - - export interface SentryCliReleases { - ['new'](release: string, options?: { projects: string[] } | string[]): Promise; - - setCommits(release: string, options: SentryCliCommitsOptions): Promise; - - finalize(release: string): Promise; - - proposeVersion(): Promise; - - uploadSourceMaps( - release: string, - options: SentryCliUploadSourceMapsOptions & { live?: boolean | 'rejectOnError' } - ): Promise; - - listDeploys(release: string): Promise; - - newDeploy(release: string, options: SentryCliNewDeployOptions): Promise; - - execute(args: string[], live: boolean | 'rejectOnError'): Promise; - } - - export default class SentryCli { - /** - * Creates a new instance of SentryCli class - * - * @param configFile Path to Sentry CLI config properties, as described in https://docs.sentry.io/learn/cli/configuration/#properties-files. - * By default, the config file is looked for upwards from the current path and defaults from ~/.sentryclirc are always loaded. - * This value will update `SENTRY_PROPERTIES` env variable. - * @param options {@link SentryCliOptions} - */ - constructor(configFile?: string | null, options?: SentryCliOptions); - - public configFile?: string; - public options?: SentryCliOptions; - public releases: SentryCliReleases; - - public static getVersion(): string; - public static getPath(): string; - public execute(args: string[], live: boolean | 'rejectOnError'): Promise; - } -} diff --git a/js/index.js b/js/index.js index fd70b0f0c3..288ad49e59 100644 --- a/js/index.js +++ b/js/index.js @@ -4,6 +4,15 @@ const pkgInfo = require('../package.json'); const helper = require('./helper'); const Releases = require('./releases'); +/** + * @typedef {import('./types').SentryCliOptions} SentryCliOptions + * @typedef {import('./types').SentryCliUploadSourceMapsOptions} SentryCliUploadSourceMapsOptions + * @typedef {import('./types').SourceMapsPathDescriptor} SourceMapsPathDescriptor + * @typedef {import('./types').SentryCliNewDeployOptions} SentryCliNewDeployOptions + * @typedef {import('./types').SentryCliCommitsOptions} SentryCliCommitsOptions + * @typedef {import('./types').SentryCliReleases} SentryCliReleases + */ + /** * Interface to and wrapper around the `sentry-cli` executable. * @@ -27,8 +36,10 @@ class SentryCli { * location and the value specified in the `SENTRY_PROPERTIES` environment variable is * overridden. * - * @param {string} [configFile] Relative or absolute path to the configuration file. - * @param {Object} [options] More options to pass to the CLI + * @param {string | null} [configFile] - Path to Sentry CLI config properties, as described in https://docs.sentry.io/learn/cli/configuration/#properties-files. + * By default, the config file is looked for upwards from the current path and defaults from ~/.sentryclirc are always loaded. + * This value will update `SENTRY_PROPERTIES` env variable. + * @param {SentryCliOptions} [options] - More options to pass to the CLI */ constructor(configFile, options) { if (typeof configFile === 'string') { @@ -62,7 +73,7 @@ class SentryCli { * - `false` to not inherit stdio and return the output as a string. * - `'rejectOnError'` to inherit stdio and reject the promise if the command * exits with a non-zero exit code. - * @returns {Promise.} A promise that resolves to the standard output. + * @returns {Promise} A promise that resolves to the standard output. */ execute(args, live) { return helper.execute(args, live, this.options.silent, this.configFile, this.options); diff --git a/js/releases/index.js b/js/releases/index.js index c3fa261d66..d257bf728f 100644 --- a/js/releases/index.js +++ b/js/releases/index.js @@ -20,6 +20,13 @@ const SOURCEMAPS_SCHEMA = require('./options/uploadSourcemaps'); */ const DEPLOYS_SCHEMA = require('./options/deploys'); +/** + * @typedef {import('../types').SentryCliUploadSourceMapsOptions} SentryCliUploadSourceMapsOptions + * @typedef {import('../types').SourceMapsPathDescriptor} SourceMapsPathDescriptor + * @typedef {import('../types').SentryCliNewDeployOptions} SentryCliNewDeployOptions + * @typedef {import('../types').SentryCliCommitsOptions} SentryCliCommitsOptions + */ + /** * Manages releases and release artifacts on Sentry. * @namespace SentryReleases @@ -45,9 +52,8 @@ class Releases { * upload artifacts, such as source maps. * * @param {string} release Unique name of the new release. - * @param {object} options A set of options when creating a release. - * @param {array} options.projects The list of project slugs for a release. - * @returns {Promise} A promise that resolves when the release has been created. + * @param {{projects?: string[]}} [options] A set of options when creating a release, or an array of project slugs. + * @returns {Promise} A promise that resolves when the release has been created. * @memberof SentryReleases */ async new(release, options) { @@ -59,21 +65,8 @@ class Releases { * Specifies the set of commits covered in this release. * * @param {string} release Unique name of the release - * @param {object} options A set of options to configure the commits to include - * @param {string} options.repo The full repo name as defined in Sentry - * @param {boolean} options.auto Automatically choose the associated commit (uses - * the current commit). Overrides other options. - * @param {string} options.commit The current (last) commit in the release. - * @param {string} options.previousCommit The commit before the beginning of this - * release (in other words, the last commit of the previous release). If omitted, - * this will default to the last commit of the previous release in Sentry. If there - * was no previous release, the last 10 commits will be used. - * @param {boolean} options.ignoreMissing When the flag is set and the previous release - * commit was not found in the repository, will create a release with the default commits - * count (or the one specified with `--initial-depth`) instead of failing the command. - * @param {boolean} options.ignoreEmpty When the flag is set, command will not fail - * and just exit silently if no new commits for a given release have been found. - * @returns {Promise} A promise that resolves when the commits have been associated + * @param {SentryCliCommitsOptions} options A set of options to configure the commits to include + * @returns {Promise} A promise that resolves when the commits have been associated * @memberof SentryReleases */ async setCommits(release, options) { @@ -103,7 +96,7 @@ class Releases { * uploaded. * * @param {string} release Unique name of the release. - * @returns {Promise} A promise that resolves when the release has been finalized. + * @returns {Promise} A promise that resolves when the release has been finalized. * @memberof SentryReleases */ async finalize(release) { @@ -114,7 +107,7 @@ class Releases { * Creates a unique, deterministic version identifier based on the project type and * source files. This identifier can be used as release name. * - * @returns {Promise.} A promise that resolves to the version string. + * @returns {Promise} A promise that resolves to the version string. * @memberof SentryReleases */ async proposeVersion() { @@ -153,8 +146,8 @@ class Releases { * }); * * @param {string} release Unique name of the release. - * @param {object} options Options to configure the source map upload. - * @returns {Promise} A promise that resolves when the upload has completed successfully. + * @param {SentryCliUploadSourceMapsOptions & {live?: boolean | 'rejectOnError'}} options Options to configure the source map upload. + * @returns {Promise} A promise that resolves when the upload has completed successfully. * @memberof SentryReleases */ async uploadSourceMaps(release, options) { @@ -219,7 +212,7 @@ class Releases { * List all deploys for a given release. * * @param {string} release Unique name of the release. - * @returns {Promise} A promise that resolves when the list comes back from the server. + * @returns {Promise} A promise that resolves when the list comes back from the server. * @memberof SentryReleases */ async listDeploys(release) { @@ -244,8 +237,8 @@ class Releases { * }); * * @param {string} release Unique name of the release. - * @param {object} options Options to configure the new release deploy. - * @returns {Promise} A promise that resolves when the deploy has been created. + * @param {SentryCliNewDeployOptions} options Options to configure the new release deploy. + * @returns {Promise} A promise that resolves when the deploy has been created. * @memberof SentryReleases */ async newDeploy(release, options) { @@ -264,7 +257,7 @@ class Releases { * - `false` to not inherit stdio and return the output as a string. * - `'rejectOnError'` to inherit stdio and reject the promise if the command * exits with a non-zero exit code. - * @returns {Promise.} A promise that resolves to the standard output. + * @returns {Promise} A promise that resolves to the standard output. */ async execute(args, live) { return helper.execute(args, live, this.options.silent, this.configFile, this.options); diff --git a/js/types.ts b/js/types.ts new file mode 100644 index 0000000000..4e703921ea --- /dev/null +++ b/js/types.ts @@ -0,0 +1,244 @@ +/** + * TypeScript type definitions for @sentry/cli + */ + +/** + * Options for configuring the Sentry CLI + */ +export interface SentryCliOptions { + /** + * The URL of the Sentry instance you are connecting to. Defaults to https://sentry.io/. + * This value will update `SENTRY_URL` env variable. + */ + url?: string; + /** + * Authentication token for HTTP requests to Sentry. + * This value will update `SENTRY_AUTH_TOKEN` env variable. + */ + authToken?: string; + /** + * API key to authenticate any HTTP requests to Sentry (legacy authentication method). + * This value will update `SENTRY_API_KEY` env variable. + * @deprecated Use auth-token-based authentication via `authToken` instead. + * This option is scheduled for removal in the next major release. + */ + apiKey?: string; + /** + * Sentry DSN. + * This value will update `SENTRY_DSN` env variable. + */ + dsn?: string; + /** + * Organization slug. + * This value will update `SENTRY_ORG` env variable. + */ + org?: string; + /** + * Project slug. + * This value will update `SENTRY_PROJECT` env variable. + */ + project?: string; + /** + * Version control system remote name. + * This value will update `SENTRY_VCS_REMOTE` env variable. + */ + vcsRemote?: string; + /** + * If true, all logs are suppressed. + */ + silent?: boolean; + /** + * A header added to every outgoing network request. + * This value will update `CUSTOM_HEADER` env variable. + */ + customHeader?: string; + /** + * Headers added to every outgoing network request. + * This value does not set any env variable, and is overridden by `customHeader`. + */ + headers?: Record; +} + +/** + * Custom upload-sourcemaps options for a particular `include` path. In this + * case `paths` takes the place of `include` in the options so as to make it + * clear that this is not recursive. + */ +export type SourceMapsPathDescriptor = Omit & { + paths: string[]; +}; + + +/** + * Options for uploading source maps + */ +export interface SentryCliUploadSourceMapsOptions { + /** + * One or more paths that Sentry CLI should scan recursively for sources. + * It will upload all .map files and match associated .js files. + */ + include: Array; + /** + * One or more paths to ignore during upload. Overrides entries in ignoreFile file. + */ + ignore?: string[]; + /** + * Path to a file containing list of files/directories to ignore. + * Can point to .gitignore or anything with same format. + */ + ignoreFile?: string | null; + /** + * Enables rewriting of matching sourcemaps so that indexed maps are flattened + * and missing sources are inlined if possible. Defaults to `true`. + */ + rewrite?: boolean; + /** + * This prevents the automatic detection of sourcemap references. + */ + sourceMapReference?: boolean; + /** + * Enables files gzip decompression prior to uploading. Defaults to `false`. + */ + decompress?: boolean; + /** + * Enable artifacts deduplication prior to uploading. This will skip uploading + * any artifacts that are already present on the server. Defaults to `true`. + */ + dedupe?: boolean; + /** + * When paired with the rewrite option this will remove a prefix from uploaded files. + * For instance you can use this to remove a path that is build machine specific. + */ + stripPrefix?: string[]; + /** + * When paired with the rewrite option this will add ~ to the stripPrefix array. + */ + stripCommonPrefix?: boolean; + /** + * The projects to upload the sourcemaps to. If not provided, the sourcemaps will be uploaded to the default project. + */ + projects?: string[]; + /** + * This attempts sourcemap validation before upload when rewriting is not enabled. + * It will spot a variety of issues with source maps and cancel the upload if any are found. + * This is not enabled by default as this can cause false positives. + */ + validate?: boolean; + /** + * This sets an URL prefix at the beginning of all files. + * This defaults to `~/` but you might want to set this to the full URL. + * This is also useful if your files are stored in a sub folder. eg: url-prefix `~/static/js`. + */ + urlPrefix?: string; + /** + * This sets an URL suffix at the end of all files. + * Useful for appending query parameters. + */ + urlSuffix?: string; + /** + * This sets the file extensions to be considered. + * By default the following file extensions are processed: js, map, jsbundle and bundle. + */ + ext?: string[]; + /** + * Unique identifier for the distribution, used to further segment your release. + * Usually your build number. + */ + dist?: string; + /** + * Force use of new Artifact Bundles upload, that enables use of Debug ID for Source Maps discovery, + * even when the Sentry server does not declare support for it. + * + * @deprecated This option is deprecated and will be removed in the next major version. Sentry CLI + * should always respect what the server says it supports. + */ + useArtifactBundle?: boolean; +} + +/** + * Options for creating a new deployment + */ +export interface SentryCliNewDeployOptions { + /** + * Environment for this release. Values that make sense here would be `production` or `staging`. + */ + env: string; + /** + * Deployment start time in Unix timestamp (in seconds) or ISO 8601 format. + */ + started?: number | string; + /** + * Deployment finish time in Unix timestamp (in seconds) or ISO 8601 format. + */ + finished?: number | string; + /** + * Deployment duration (in seconds). Can be used instead of started and finished. + */ + time?: number; + /** + * Human readable name for the deployment. + */ + name?: string; + /** + * URL that points to the deployment. + */ + url?: string; +} + +/** + * Options for setting commits on a release + */ +export interface SentryCliCommitsOptions { + /** + * Automatically choose the associated commit (uses the current commit). Overrides other setCommit options. + */ + auto?: boolean; + /** + * The full repo name as defined in Sentry. Required if auto option is not true. + */ + repo?: string; + /** + * The current (last) commit in the release. Required if auto option is not true. + */ + commit?: string; + /** + * The commit before the beginning of this release (in other words, the last commit of the previous release). + * If omitted, this will default to the last commit of the previous release in Sentry. + * If there was no previous release, the last 10 commits will be used. + */ + previousCommit?: string; + /** + * When the flag is set and the previous release commit was not found in the repository, will create a release + * with the default commits count(or the one specified with `--initial-depth`) instead of failing the command. + */ + ignoreMissing?: boolean; + /** + * When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found. + */ + ignoreEmpty?: boolean; +} + +/** + * Release management interface + */ +export interface SentryCliReleases { + new(release: string, options?: { projects: string[] } | string[]): Promise; + + setCommits(release: string, options: SentryCliCommitsOptions): Promise; + + finalize(release: string): Promise; + + proposeVersion(): Promise; + + uploadSourceMaps( + release: string, + options: SentryCliUploadSourceMapsOptions & { live?: boolean | 'rejectOnError' } + ): Promise; + + listDeploys(release: string): Promise; + + newDeploy(release: string, options: SentryCliNewDeployOptions): Promise; + + execute(args: string[], live: boolean | 'rejectOnError'): Promise; +} + diff --git a/tsconfig.json b/tsconfig.json index 0cf30654ec..5bd209aca6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,8 @@ "moduleResolution": "node", "skipLibCheck": true, "rootDir": "js", - "outDir": "js-dist" + "outDir": "js-dist", + "declaration": true }, "include": ["js/**/*.ts", "js/**/*.js"], "exclude": ["**/__tests__/**", "**/__mocks__/**"] From 6d04477d36b8c415976271c44a249154a5b3c3f5 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 4 Nov 2025 14:44:49 +0100 Subject: [PATCH 3/4] chore: Update cursor hints for JavaScript development --- .cursor/rules/javascript-development.mdc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.cursor/rules/javascript-development.mdc b/.cursor/rules/javascript-development.mdc index d82f73e6e7..c87041a36b 100644 --- a/.cursor/rules/javascript-development.mdc +++ b/.cursor/rules/javascript-development.mdc @@ -9,7 +9,6 @@ alwaysApply: false ## Code Organization - Maintain compatibility with existing npm package structure -- Update TypeScript definitions in `js/index.d.ts` if needed - Consider impact on installation flow in `scripts/install.js` - Test across different Node.js versions @@ -36,6 +35,6 @@ npm run check:types ## TypeScript Support -- Type definitions maintained in `js/index.d.ts` +- Type definitions are generated via TypeScript - Sync with Rust CLI interface changes - Consider backward compatibility for JS API From be48e799106dfdaecf660137b1ba47d09bbd0b1b Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 4 Nov 2025 15:24:57 +0100 Subject: [PATCH 4/4] chore: prebuild dist folder | add changelog --- .cursor/rules/sentry-cli-project.mdc | 2 +- .github/CODEOWNERS | 2 +- .github/workflows/test_node.yml | 36 +++++++++++++++++-- .gitignore | 2 +- .npmignore | 2 +- CHANGELOG.md | 4 +++ bin/sentry-cli | 2 +- {js => lib}/__mocks__/sentry-cli | 0 {js => lib}/__tests__/helper.test.js | 0 {js => lib}/helper.js | 0 {js => lib}/index.js | 0 {js => lib}/logger.js | 0 {js => lib}/releases/__tests__/index.test.js | 0 {js => lib}/releases/index.js | 2 +- {js => lib}/releases/options/deploys.js | 0 .../releases/options/uploadSourcemaps.js | 0 {js => lib}/types.ts | 0 package.json | 16 +++++---- scripts/install.js | 4 +-- setupTests.js | 2 +- tsconfig.json | 6 ++-- 21 files changed, 59 insertions(+), 21 deletions(-) rename {js => lib}/__mocks__/sentry-cli (100%) rename {js => lib}/__tests__/helper.test.js (100%) rename {js => lib}/helper.js (100%) rename {js => lib}/index.js (100%) rename {js => lib}/logger.js (100%) rename {js => lib}/releases/__tests__/index.test.js (100%) rename {js => lib}/releases/index.js (98%) rename {js => lib}/releases/options/deploys.js (100%) rename {js => lib}/releases/options/uploadSourcemaps.js (100%) rename {js => lib}/types.ts (100%) diff --git a/.cursor/rules/sentry-cli-project.mdc b/.cursor/rules/sentry-cli-project.mdc index 47ae894f4f..2a80dfaa30 100644 --- a/.cursor/rules/sentry-cli-project.mdc +++ b/.cursor/rules/sentry-cli-project.mdc @@ -20,7 +20,7 @@ This is **sentry-cli**, a command-line utility for working with Sentry. It's pri ## Project Structure - `src/` - Core Rust source code with command modules and utilities -- `js/` - JavaScript wrapper and npm package code +- `lib/` - JavaScript wrapper and npm package code - `scripts/` - Build and utility scripts - `tests/integration/` - Integration tests using `.trycmd` format - `npm-binary-distributions/` - Platform-specific binary packages diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cc2b33b35b..8fbb8ffe7b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,7 +4,7 @@ /.cursor/rules/javascript-development.mdc @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli /.npmignore @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli /bin/ @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli # these are the JS "binaries" -/js @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli +/lib @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli /package.json @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli /scripts/*.js @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli /tsconfig.json @getsentry/team-javascript-sdks @getsentry/owners-sentry-cli diff --git a/.github/workflows/test_node.yml b/.github/workflows/test_node.yml index 12f53e6129..8b54425791 100644 --- a/.github/workflows/test_node.yml +++ b/.github/workflows/test_node.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies via npm ci if: ${{ !inputs.triggered-by-release }} - run: npm ci + run: npm ci --ignore-scripts # For pushes to the release branch, we need to install the dependencies via `npm install` # because the `package-lock.json` is not updated with the new versions of the optional @@ -37,7 +37,30 @@ jobs: - run: npm run check:types + prepare_build: + name: Prepare Build + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # 5.0.0 + + - name: Use Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # 6.0.0 + with: + node-version-file: package.json + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: Build + run: npm run build + + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2 + with: + name: artifact-build + path: js + test_node: + needs: prepare_build strategy: fail-fast: false matrix: @@ -56,7 +79,7 @@ jobs: - name: Install dependencies via npm ci if: ${{ !inputs.triggered-by-release }} - run: npm ci + run: npm ci --ignore-scripts # For pushes to the release branch, we need to install the dependencies via `npm install` # because the `package-lock.json` is not updated with the new versions of the optional @@ -65,6 +88,15 @@ jobs: if: ${{ inputs.triggered-by-release }} run: npm install --omit=optional --ignore-scripts + - name: Download build artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # 5.0.0 + with: + name: artifact-build + path: js + + - name: Install CLI + run: npm run install-cli + # older node versions need an older nft - run: SENTRYCLI_SKIP_DOWNLOAD=1 npm install @vercel/nft@0.22.1 if: matrix.node-version == '10.x' || matrix.node-version == '12.x' diff --git a/.gitignore b/.gitignore index e5fb9fbff4..38cb376d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ target node_modules coverage dist -js-dist +js dump checksums.txt yarn-error.log diff --git a/.npmignore b/.npmignore index 332009cf15..b758a43b1d 100644 --- a/.npmignore +++ b/.npmignore @@ -6,7 +6,7 @@ !README.md !LICENSE !bin/sentry-cli -!js-dist +!js !scripts/install.js !checksums.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 983c4f97a9..5a376b6a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,10 @@ - Slightly sped up the `sentry-cli sourcemaps upload` command by eliminating an HTTP request to the Sentry server, which was not required in most cases ([#2913](https://github.com/getsentry/sentry-cli/pull/2913)). +### Internal changes + +- Migrated JavaScript wrapper to TypeScript for better type safety ([#2910](https://github.com/getsentry/sentry-cli/pull/2910)) + ## 2.57.0 ### New Features diff --git a/bin/sentry-cli b/bin/sentry-cli index 667d4d360c..81fb8c6f65 100755 --- a/bin/sentry-cli +++ b/bin/sentry-cli @@ -3,7 +3,7 @@ 'use strict'; const childProcess = require('child_process'); -const SentryCli = require('../js-dist'); +const SentryCli = require('../js'); const child = childProcess .spawn(SentryCli.getPath(), process.argv.slice(2), { diff --git a/js/__mocks__/sentry-cli b/lib/__mocks__/sentry-cli similarity index 100% rename from js/__mocks__/sentry-cli rename to lib/__mocks__/sentry-cli diff --git a/js/__tests__/helper.test.js b/lib/__tests__/helper.test.js similarity index 100% rename from js/__tests__/helper.test.js rename to lib/__tests__/helper.test.js diff --git a/js/helper.js b/lib/helper.js similarity index 100% rename from js/helper.js rename to lib/helper.js diff --git a/js/index.js b/lib/index.js similarity index 100% rename from js/index.js rename to lib/index.js diff --git a/js/logger.js b/lib/logger.js similarity index 100% rename from js/logger.js rename to lib/logger.js diff --git a/js/releases/__tests__/index.test.js b/lib/releases/__tests__/index.test.js similarity index 100% rename from js/releases/__tests__/index.test.js rename to lib/releases/__tests__/index.test.js diff --git a/js/releases/index.js b/lib/releases/index.js similarity index 98% rename from js/releases/index.js rename to lib/releases/index.js index d257bf728f..f03ea05130 100644 --- a/js/releases/index.js +++ b/lib/releases/index.js @@ -52,7 +52,7 @@ class Releases { * upload artifacts, such as source maps. * * @param {string} release Unique name of the new release. - * @param {{projects?: string[]}} [options] A set of options when creating a release, or an array of project slugs. + * @param {{projects?: string[]}} [options] The list of project slugs for a release. * @returns {Promise} A promise that resolves when the release has been created. * @memberof SentryReleases */ diff --git a/js/releases/options/deploys.js b/lib/releases/options/deploys.js similarity index 100% rename from js/releases/options/deploys.js rename to lib/releases/options/deploys.js diff --git a/js/releases/options/uploadSourcemaps.js b/lib/releases/options/uploadSourcemaps.js similarity index 100% rename from js/releases/options/uploadSourcemaps.js rename to lib/releases/options/uploadSourcemaps.js diff --git a/js/types.ts b/lib/types.ts similarity index 100% rename from js/types.ts rename to lib/types.ts diff --git a/package.json b/package.json index 82f4e6a70c..626fbb1fa2 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "engines": { "node": ">= 10" }, - "main": "js-dist/index.js", - "types": "js-dist/index.d.ts", + "main": "js/index.js", + "types": "js/index.d.ts", "bin": { "sentry-cli": "bin/sentry-cli" }, @@ -42,17 +42,19 @@ "@sentry/cli-win32-arm64": "2.58.2" }, "scripts": { - "postinstall": "npm run build && node ./scripts/install.js", + "postinstall": "npm run install-cli", "build": "tsc", + "postbuild": "npm run install-cli", + "install-cli": "node ./scripts/install.js", "prepack": "npm run build", "fix": "npm-run-all fix:eslint fix:prettier", - "fix:eslint": "eslint --fix bin/* scripts/**/*.js js/**/*.js", - "fix:prettier": "prettier --write bin/* scripts/**/*.js js/**/*.js", + "fix:eslint": "eslint --fix bin/* scripts/**/*.js lib/**/*.js", + "fix:prettier": "prettier --write bin/* scripts/**/*.js lib/**/*.js", "test": "npm-run-all test:jest test:eslint test:prettier test:vercel-nft", "test:jest": "jest", "test:watch": "jest --watch --notify", - "test:eslint": "eslint bin/* scripts/**/*.js js/**/*.js", - "test:prettier": "prettier --check bin/* scripts/**/*.js js/**/*.js", + "test:eslint": "eslint bin/* scripts/**/*.js lib/**/*.js", + "test:prettier": "prettier --check bin/* scripts/**/*.js lib/**/*.js", "check:types": "tsc --noEmit", "test:vercel-nft": "node scripts/test-vercel-nft.js" }, diff --git a/scripts/install.js b/scripts/install.js index 3324bcf260..eb1fb94987 100755 --- a/scripts/install.js +++ b/scripts/install.js @@ -16,9 +16,9 @@ const ProgressBar = require('progress'); const Proxy = require('proxy-from-env'); const which = require('which'); -const helper = require('../js-dist/helper'); +const helper = require('../js/helper'); const pkgInfo = require('../package.json'); -const Logger = require('../js-dist/logger'); +const Logger = require('../js/logger'); const logger = new Logger(getLogStream('stderr')); diff --git a/setupTests.js b/setupTests.js index 931104a4ba..ced164eb32 100644 --- a/setupTests.js +++ b/setupTests.js @@ -1,3 +1,3 @@ const path = require('path'); -process.env.SENTRY_BINARY_PATH = path.join(__dirname, 'js', '__mocks__', 'sentry-cli'); +process.env.SENTRY_BINARY_PATH = path.join(__dirname, 'lib', '__mocks__', 'sentry-cli'); diff --git a/tsconfig.json b/tsconfig.json index 5bd209aca6..b36b57978d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,10 +6,10 @@ "target": "ES2015", "moduleResolution": "node", "skipLibCheck": true, - "rootDir": "js", - "outDir": "js-dist", + "rootDir": "lib", + "outDir": "js", "declaration": true }, - "include": ["js/**/*.ts", "js/**/*.js"], + "include": ["lib/**/*.ts", "lib/**/*.js"], "exclude": ["**/__tests__/**", "**/__mocks__/**"] }