Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@hubspot/npm-scripts

Package Overview
Dependencies
Maintainers
40
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hubspot/npm-scripts - npm Package Compare versions

Comparing version
0.0.5-experimental.0
to
0.0.5-experimental.1
+1
-1
package.json
{
"name": "@hubspot/npm-scripts",
"version": "0.0.5-experimental.0",
"version": "0.0.5-experimental.1",
"description": "Scripts for working with npm packages in the HubSpot ecosystem",

@@ -5,0 +5,0 @@ "author": "",

@@ -43,7 +43,3 @@ import { TAG, TAG_OPTIONS, VERSION_INCREMENT_OPTIONS, VSCODE_VERSION_INCREMENT_OPTIONS } from './constants/release.js';

export interface VscodeReleaseScriptBase {
repositoryUrl: string;
mainBranch?: string;
marketplaceUrl: string;
extensionName: string;
slackChannel?: string;
build?: () => Promise<void> | void;

@@ -50,0 +46,0 @@ }

@@ -1,2 +0,2 @@

import { exec as _exec, spawn } from 'node:child_process';
import { exec as _exec } from 'node:child_process';
import { promisify } from 'util';

@@ -13,71 +13,3 @@ import yargs from 'yargs';

const exec = promisify(_exec);
function runVsceCommand(script) {
return new Promise((resolve, reject) => {
const child = spawn('yarn', [script], {
stdio: ['pipe', 'inherit', 'inherit'],
});
child.stdin?.write('y\n');
child.stdin?.end();
child.on('close', code => {
if (code !== EXIT_CODES.SUCCESS) {
reject(new Error(`"yarn ${script}" failed with exit code ${code}`));
}
else {
resolve();
}
});
});
}
async function getLastTag() {
try {
const { stdout } = await exec('git describe --tags --abbrev=0');
return stdout.trim();
}
catch {
return null;
}
}
async function createDraftPR({ baseBranch, title, body, }) {
logger.log('\nCreating draft pull request...');
try {
const { stdout } = await exec(`gh pr create --draft --base ${baseBranch} --title "${title}" --body "${body.replace(/"/g, '\\"')}"`);
const prUrl = stdout.trim();
logger.success(`Draft PR created: ${prUrl}`);
return prUrl;
}
catch (error) {
logger.error('Failed to create pull request:', error);
process.exit(EXIT_CODES.ERROR);
}
}
async function createGithubRelease({ tag, title, notes, }) {
logger.log('\nCreating GitHub release...');
try {
const { stdout } = await exec(`gh release create ${tag} --title "${title}" --notes "${notes.replace(/"/g, '\\"')}" --draft`);
const releaseUrl = stdout.trim();
logger.success(`Draft GitHub release created: ${releaseUrl}`);
return releaseUrl;
}
catch (error) {
logger.error('Failed to create GitHub release:', error);
process.exit(EXIT_CODES.ERROR);
}
}
function generateSlackMessage({ extensionName, version, marketplaceUrl, repositoryUrl, }) {
return [
`\u{1F4E6} ${extensionName} VSCode Extension v${version} Released`,
'',
'*Links:*',
`- Marketplace: ${marketplaceUrl}`,
`- Changelog: ${repositoryUrl}/blob/master/CHANGELOG.md`,
].join('\n');
}
function printSlackMessage(message, channel) {
logger.log('\n' + '='.repeat(60));
logger.log(`Slack message for ${channel}:`);
logger.log('='.repeat(60));
logger.log(message);
logger.log('='.repeat(60));
}
function buildHandler({ build, packageName, localVersion, repositoryUrl, mainBranch, marketplaceUrl, extensionName, slackChannel, }) {
function buildHandler({ build, packageName, localVersion, mainBranch, }) {
return async function handler({ versionIncrement, dryRun, skipTests, }) {

@@ -87,3 +19,2 @@ try {

const isDryRun = Boolean(dryRun);
const resolvedSlackChannel = slackChannel || '#cli-dev';
if (branch !== mainBranch) {

@@ -93,2 +24,18 @@ logger.error(`Releases can only be published from the ${mainBranch} branch. Current branch: ${branch}`);

}
const newVersion = semver.inc(localVersion, versionIncrement);
if (!newVersion) {
logger.error('Error incrementing version.');
process.exit(EXIT_CODES.ERROR);
}
if (isDryRun) {
logger.log('\nDRY RUN');
}
logger.log(`\nCurrent version: ${localVersion}`);
logger.log(`New version to release: ${newVersion}`);
const shouldRelease = await confirm({
message: `Release version ${newVersion}?`,
});
if (!shouldRelease) {
process.exit(EXIT_CODES.SUCCESS);
}
if (!skipTests) {

@@ -111,3 +58,3 @@ const userHasTested = await confirm({

logger.log('\nPackaging pre-release...');
await runVsceCommand('vsce:prerelease');
await exec('npx vsce package --pre-release -o releases/');
logger.success('Pre-release package created.');

@@ -130,41 +77,7 @@ logger.log('\nTo test the package locally:');

}
const newVersion = semver.inc(localVersion, versionIncrement);
if (!newVersion) {
logger.error('Error incrementing version.');
process.exit(EXIT_CODES.ERROR);
}
if (isDryRun) {
logger.log('\nDRY RUN');
}
logger.log(`\nCurrent version: ${localVersion}`);
logger.log(`New version to release: ${newVersion}`);
const shouldRelease = await confirm({
message: `Release version ${newVersion}?`,
});
if (!shouldRelease) {
process.exit(EXIT_CODES.SUCCESS);
}
logger.log(`\nUpdating version to ${newVersion}...`);
await exec(`yarn version --no-git-tag-version --new-version ${newVersion}`);
logger.success('Version updated in package.json');
const lastTag = await getLastTag();
if (lastTag) {
logger.log(`\nUpdate CHANGELOG.md with the changes since ${lastTag}:`);
logger.log(` ${repositoryUrl}/compare/${lastTag}...${mainBranch}`);
await open(`${repositoryUrl}/compare/${lastTag}...${mainBranch}`);
}
else {
logger.log('\nUpdate CHANGELOG.md with the changes for this release.');
}
const changelogUpdated = await confirm({
message: 'Have you updated CHANGELOG.md?',
default: false,
});
if (!changelogUpdated) {
logger.log('Release aborted.');
logger.log('Note: package.json version has been updated locally. Revert if needed.');
process.exit(EXIT_CODES.SUCCESS);
}
logger.log('\nPackaging regular release...');
await runVsceCommand('vsce:package');
await exec('npx vsce package -o releases/');
logger.success('Regular release package created.');

@@ -177,20 +90,14 @@ const confirmRegularRelease = await confirm({

logger.log('Release aborted after regular release packaging.');
logger.log('Note: package.json version and CHANGELOG.md have been updated locally. Revert if needed.');
logger.log('Note: package.json version has been updated locally. Revert if needed.');
process.exit(EXIT_CODES.SUCCESS);
}
const releaseBranch = `release/v${newVersion}`;
const releaseNotes = 'See CHANGELOG.md for details.';
if (isDryRun) {
logger.log(`\nDry run: would create branch ${releaseBranch}`);
logger.log('Dry run: would commit package.json + CHANGELOG.md');
logger.log(`Dry run: would push ${releaseBranch}`);
logger.log(`Dry run: would create draft PR against ${mainBranch}`);
logger.log(`Dry run: would create draft GH release v${newVersion}`);
printSlackMessage(generateSlackMessage({
extensionName,
version: newVersion,
marketplaceUrl,
repositoryUrl,
}), resolvedSlackChannel);
logger.log('\nDry run release finished successfully.');
logger.log('\nDry run complete. Would have:');
logger.log(` 1. Created branch ${releaseBranch}`);
logger.log(` 2. Committed package.json version bump`);
logger.log(` 3. Pushed ${releaseBranch} to origin`);
logger.log(` 4. Created draft PR against ${mainBranch}`);
logger.log(` 5. Created draft GH release v${newVersion}`);
logger.log(` 6. Opened VS Code Marketplace for .vsix upload`);
process.exit(EXIT_CODES.SUCCESS);

@@ -201,30 +108,16 @@ }

logger.log('Committing changes...');
await exec('git add package.json CHANGELOG.md');
await exec('git add package.json');
await exec(`git commit -m "Bump version to ${newVersion}"`);
logger.log(`Pushing ${releaseBranch}...`);
await exec(`git push -u origin ${releaseBranch}`);
const prUrl = await createDraftPR({
baseBranch: mainBranch,
title: `Release v${newVersion}`,
body: `## Release v${newVersion}\n\n${releaseNotes}`,
});
const releaseUrl = await createGithubRelease({
tag: `v${newVersion}`,
title: `Version ${newVersion}`,
notes: releaseNotes,
});
printSlackMessage(generateSlackMessage({
extensionName,
version: newVersion,
marketplaceUrl,
repositoryUrl,
}), resolvedSlackChannel);
logger.log('\nCreating draft pull request...');
const { stdout: prUrl } = await exec(`gh pr create --draft --base ${mainBranch} --title "Release v${newVersion}" --body "## Release v${newVersion}"`);
logger.success(`Draft PR created: ${prUrl.trim()}`);
logger.log('\nCreating draft GitHub release...');
const { stdout: releaseUrl } = await exec(`gh release create v${newVersion} --title "Version ${newVersion}" --notes "" --draft`);
logger.success(`Draft GitHub release created: ${releaseUrl.trim()}`);
logger.log('\nNext steps:');
logger.log(' 1. Upload the .vsix file to the VS Code Marketplace:');
logger.log(` ${marketplaceUrl.replace('/items?itemName=', '/manage/publishers/')}`);
logger.log(' 2. Copy the Slack message above and post it');
logger.log(` 3. Merge the PR: ${prUrl}`);
if (releaseUrl) {
logger.log(` 4. Publish the GH release: ${releaseUrl}`);
}
logger.log(' 1. Upload the .vsix file to the VS Code Marketplace');
logger.log(` 2. Merge the PR: ${prUrl.trim()}`);
logger.log(` 3. Publish the GH release: ${releaseUrl.trim()}`);
await open('https://marketplace.visualstudio.com/manage/publishers/hubspot');

@@ -231,0 +124,0 @@ logger.success(`\n${packageName} version ${newVersion} release prepared successfully!`);