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
1,214 changes: 305 additions & 909 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"date-fns": "^2.30.0",
"debug": "^4.4.3",
"eventsource": "^4",
"execa": "5.1.1",
"execa": "^9.6.1",
"filesize": "^10.1",
"foreman": "^3.0.1",
"fs-extra": "^11.3.0",
Expand Down Expand Up @@ -130,7 +130,6 @@
"mock-stdin": "^1",
"nock": "^14.0.12",
"oclif": "^4.22.87",
"qqjs": "0.3.11",
"rimraf": "5.0.5",
"sinon": "^21.0.2",
"source-map-support": "^0.5.21",
Expand Down
37 changes: 14 additions & 23 deletions scripts/postrelease/install-scripts.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#!/usr/bin/env node

import execa from 'execa'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import qq from 'qqjs'

import getHerokuS3Bucket from '../utils/get-heroku-s3-bucket.js'
import isStableRelease from '../utils/is-stable-release.js'
import {run, shell} from '../utils/script-exec.js'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
Expand All @@ -16,25 +15,17 @@ const opts = {
stdio: 'inherit',
}

qq.config.silent = false
await run(async () => {
const {GITHUB_REF_NAME, GITHUB_REF_TYPE} = process.env

try {
await qq.run(async () => {
const {GITHUB_REF_NAME, GITHUB_REF_TYPE} = process.env

if (isStableRelease(GITHUB_REF_TYPE, GITHUB_REF_NAME)) {
const HEROKU_S3_BUCKET = await getHerokuS3Bucket()
await execa.command(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-standalone.sh s3://${HEROKU_S3_BUCKET}/install-standalone.sh`, opts)
await execa.command(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-standalone.sh s3://${HEROKU_S3_BUCKET}/install.sh`, opts)
await execa.command(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-ubuntu.sh s3://${HEROKU_S3_BUCKET}/install-ubuntu.sh`, opts)
} else {
console.log('Not on stable release, skipping updating install scripts')
// eslint-disable-next-line n/no-process-exit
process.exit(0)
}
})
} catch (error) {
console.error(error)
// eslint-disable-next-line n/no-process-exit
process.exit(1)
}
if (isStableRelease(GITHUB_REF_TYPE, GITHUB_REF_NAME)) {
const HEROKU_S3_BUCKET = await getHerokuS3Bucket()
await shell(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-standalone.sh s3://${HEROKU_S3_BUCKET}/install-standalone.sh`, opts)
await shell(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-standalone.sh s3://${HEROKU_S3_BUCKET}/install.sh`, opts)
await shell(`aws s3 cp --content-type text/plain --cache-control max-age=604800 ./install-ubuntu.sh s3://${HEROKU_S3_BUCKET}/install-ubuntu.sh`, opts)
} else {
console.log('Not on stable release, skipping updating install scripts')
// eslint-disable-next-line n/no-process-exit
process.exit(0)
}
})
18 changes: 7 additions & 11 deletions scripts/release/homebrew.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import execa from 'execa'
import crypto from 'node:crypto'
import fs from 'node:fs'
import path from 'node:path'
Expand All @@ -9,6 +8,7 @@ import {rimrafSync} from 'rimraf'

import getHerokuS3Bucket from '../utils/get-heroku-s3-bucket.js'
import isStableRelease from '../utils/is-stable-release.js'
import {run, shell, x} from '../utils/script-exec.js'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
Expand Down Expand Up @@ -41,7 +41,7 @@ const ARCH_ARM = 'arm64'
function downloadFileFromS3(s3Path, fileName, downloadPath) {
const downloadTo = path.join(downloadPath, fileName)
const commandStr = `aws s3 cp s3://${HEROKU_S3_BUCKET}/${s3Path}/${fileName} ${downloadTo}`
return execa.command(commandStr)
return shell(commandStr)
}

async function updateHerokuFormula(brewDir) {
Expand Down Expand Up @@ -94,7 +94,7 @@ async function updateHerokuFormula(brewDir) {

async function setupGit() {
const githubSetupPath = path.join(__dirname, '..', 'utils', '_github_setup')
await execa(githubSetupPath)
await x(githubSetupPath, [])
}

async function updateHomebrew() {
Expand All @@ -108,7 +108,7 @@ async function updateHomebrew() {
await setupGit()

console.log(`cloning https://github.com/heroku/homebrew-brew to ${homebrewDir}`)
await execa(
await x(
'git',
[
'clone',
Expand All @@ -122,7 +122,7 @@ async function updateHomebrew() {

// run in git in cloned heroku/homebrew-brew git directory
const git = async (args, opts = {}) => {
await execa('git', ['-C', homebrewDir, ...args], opts)
await x('git', ['-C', homebrewDir, ...args], opts)
}

console.log('updating local git...')
Expand All @@ -135,10 +135,6 @@ async function updateHomebrew() {
}
}

try {
await run(async () => {
await updateHomebrew()
} catch (error) {
console.error('error running scripts/release/homebrew.js', error)
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit
process.exit(1)
}
})
60 changes: 60 additions & 0 deletions scripts/utils/script-exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {execa} from 'execa'

/**
* Execute a command with args array
* Logs the command and uses stdio: 'inherit' by default
*/
export function x(command, args, options) {
console.log(`$ ${command} ${args.join(' ')}`)
return execa(command, args, {
stdio: 'inherit',
...options,
})
}

/**
* Execute a shell command (string with interpolation, pipes, etc.)
* Logs the command and uses stdio: 'inherit' by default
*/
export function shell(command, options) {
console.log(`$ ${command}`)
return execa(command, {
shell: true,
stdio: 'inherit',
...options,
})
}

/**
* Execute a command and return stdout as string
* Trims trailing newline
*/
export async function stdout(command, args, options) {
console.log(`$ ${command} ${args.join(' ')}`)
const result = await execa(command, args, {
...options,
stderr: 'inherit',
stdin: 'inherit',
stdout: 'pipe',
})
const output = typeof result.stdout === 'string' ? result.stdout : ''
return output.replace(/\n$/, '')
}

/**
* Run an async function with error handling
* Catches errors, logs them, and sets process.exitCode
*/
export async function run(fn) {
try {
return await fn()
} catch (error) {
if (error instanceof Error) {
console.error(error.stack || error.message)
} else {
console.error(error)
}

process.exitCode = 1
}
}
5 changes: 3 additions & 2 deletions scripts/utils/version.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import fs from 'node:fs'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import qq from 'qqjs'

import {stdout} from './script-exec.js'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
Expand All @@ -11,7 +12,7 @@ export default async function getVersion() {
let {version} = packageJson
if (version.includes('-')) {
const channel = version.split('-')[1].split('.')[0]
const sha = await qq.x.stdout('git', ['rev-parse', '--short', 'HEAD'])
const sha = await stdout('git', ['rev-parse', '--short', 'HEAD'])
version = `${version.split('-')[0]}-${channel}.${sha}`
}

Expand Down
15 changes: 9 additions & 6 deletions test/acceptance/plugin.acceptance.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import execa from 'execa'
import fs from 'fs-extra'
import path from 'node:path'
import {fileURLToPath} from 'node:url'

import {x} from '../../scripts/utils/script-exec.js'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const plugins = ['@heroku-cli/plugin-applink']
Expand Down Expand Up @@ -64,11 +65,13 @@ describe('plugins', function () {
cloneUrl = repoUrl
}

await execa('git', ['clone', cloneUrl, cwd])
const opts = {cwd, stdio: [0, 1, 2]}
await execa('git', ['checkout', `v${pkg.version}`], opts)
await execa('npm', [], opts)
await execa('npm', ['test'], opts)
await x('git', ['clone', cloneUrl, cwd])
const opts = {
cwd, stderr: 'inherit', stdin: 'inherit', stdout: 'inherit',
} as const
await x('git', ['checkout', `v${pkg.version}`], opts)
await x('npm', [], opts)
await x('npm', ['test'], opts)
})
}
})
5 changes: 3 additions & 2 deletions test/acceptance/smoke.acceptance.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// tslint:disable no-console
import ansis from 'ansis'
import {expect} from 'chai'
import {execa} from 'execa'
import fs from 'fs-extra'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import * as qq from 'qqjs'

import normalizeTableOutput from '../helpers/utils/normalize-table-output.js'
import commandsOutput from './commands-output.js'
Expand All @@ -16,7 +16,8 @@ const bin = path.join(__dirname, '../../bin/run')

function run(args = '') {
console.log(`$ heroku ${args}`)
return qq.x([bin, args].join(' '), {stdio: undefined})
// Use execa directly to capture output for test assertions
return execa([bin, args].join(' '), {shell: true})
}

// Smoke tests expect the CI account: heroku-cli@salesforce.com, app heroku-cli-ci-smoke-test-app,
Expand Down
Loading