Skip to content

Commit fe72a0f

Browse files
authored
Merge branch 'master' into nicholas.hulston/s3-span-pointers
2 parents d094865 + 2072a1f commit fe72a0f

6 files changed

Lines changed: 291 additions & 93 deletions

File tree

.github/workflows/release-4.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ jobs:
1616
permissions:
1717
id-token: write
1818
contents: write
19+
pull-requests: read
1920
env:
21+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2022
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2123
steps:
2224
- uses: actions/checkout@v4
@@ -31,3 +33,4 @@ jobs:
3133
- run: |
3234
git tag v${{ fromJson(steps.pkg.outputs.json).version }}
3335
git push origin v${{ fromJson(steps.pkg.outputs.json).version }}
36+
- run: node scripts/release/notes

.github/workflows/release-latest.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ jobs:
1616
permissions:
1717
id-token: write
1818
contents: write
19+
pull-requests: read
1920
env:
21+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2022
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2123
outputs:
2224
pkgjson: ${{ steps.pkg.outputs.json }}
@@ -33,6 +35,7 @@ jobs:
3335
- run: |
3436
git tag v${{ fromJson(steps.pkg.outputs.json).version }}
3537
git push origin v${{ fromJson(steps.pkg.outputs.json).version }}
38+
- run: node scripts/release/notes --latest
3639

3740
docs:
3841
runs-on: ubuntu-latest

scripts/release/helpers/requirements.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
/* eslint-disable max-len */
44

5-
const { capture, fatal } = require('./terminal')
5+
const { capture, fatal, run } = require('./terminal')
66

77
const requiredScopes = ['public_repo', 'read:org']
88

99
// Check that the `git` CLI is installed.
1010
function checkGit () {
1111
try {
12-
capture('git --version')
12+
run('git --version')
1313
} catch (e) {
1414
fatal(
1515
'The "git" CLI could not be found.',
@@ -21,7 +21,7 @@ function checkGit () {
2121
// Check that the `branch-diff` CLI is installed.
2222
function checkBranchDiff () {
2323
try {
24-
capture('branch-diff --version')
24+
run('branch-diff --version')
2525
} catch (e) {
2626
const link = [
2727
'https://datadoghq.atlassian.net/wiki/spaces/DL/pages/3125511269/Node.js+Tracer+Release+Process',
@@ -47,7 +47,7 @@ function checkGitHub () {
4747
}
4848

4949
try {
50-
capture('gh --version')
50+
run('gh --version')
5151
} catch (e) {
5252
fatal(
5353
'The "gh" CLI could not be found.',
Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
'use strict'
22

3-
/* eslint-disable no-console */
4-
53
const { execSync, spawnSync } = require('child_process')
64

7-
// Helpers for colored output.
8-
const log = (...msgs) => msgs.forEach(msg => console.log(msg))
9-
const success = (...msgs) => msgs.forEach(msg => console.log(`\x1b[32m${msg}\x1b[0m`))
10-
const error = (...msgs) => msgs.forEach(msg => console.log(`\x1b[31m${msg}\x1b[0m`))
11-
const whisper = (...msgs) => msgs.forEach(msg => console.log(`\x1b[90m${msg}\x1b[0m`))
5+
const { params, flags } = parse()
126

13-
// Helpers for exiting with a message.
14-
const exit = (...msgs) => log(...msgs) || process.exit(0)
15-
const fatal = (...msgs) => error(...msgs) || process.exit(1)
7+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
168

17-
// Output a command to the terminal and execute it.
18-
function run (cmd) {
19-
whisper(`> ${cmd}`)
9+
const BOLD = '\x1b[1m'
10+
const CYAN = '\x1b[36m'
11+
const ERASE = '\x1b[0K'
12+
const GRAY = '\x1b[90m'
13+
const GREEN = '\x1b[32m'
14+
const PREVIOUS = '\x1b[1A'
15+
const RED = '\x1b[31m'
16+
const RESET = '\x1b[0m'
2017

21-
const output = execSync(cmd, {}).toString()
18+
const print = (...msgs) => msgs.forEach(msg => process.stdout.write(msg))
19+
const log = (...msgs) => msgs.forEach(msg => print(`${msg}\n`))
20+
const fatal = (...msgs) => log(...msgs) || process.exit(1)
2221

23-
log(output)
22+
let timer
23+
let current
24+
25+
// Output a command to the terminal and execute it.
26+
function run (cmd) {
27+
capture(cmd)
2428
}
2529

2630
// Ask a question in terminal and return the response.
2731
function prompt (question) {
28-
process.stdout.write(`${question} `)
32+
print(`${BOLD}${CYAN}?${RESET} ${BOLD}${question}${RESET} `)
2933

3034
const child = spawnSync('bash', ['-c', 'read answer && echo $answer'], {
3135
stdio: ['inherit']
@@ -37,15 +41,110 @@ function prompt (question) {
3741
// Ask whether to continue and otherwise exit the process.
3842
function checkpoint (question) {
3943
const answer = prompt(`${question} [Y/n]`).trim()
44+
const prefix = `\r${PREVIOUS}${BOLD}${CYAN}?${RESET}`
45+
46+
question = `${BOLD}${question}${RESET}`
4047

4148
if (answer && answer.toLowerCase() !== 'y') {
49+
print(`\r${prefix} ${question} ${BOLD}${CYAN}No${RESET}${ERASE}\n`)
4250
process.exit(0)
51+
} else {
52+
print(`\r${prefix} ${question} ${BOLD}${CYAN}Yes${RESET}${ERASE}\n`)
4353
}
4454
}
4555

4656
// Run a command and capture its output to return it to the caller.
4757
function capture (cmd) {
48-
return execSync(cmd, {}).toString()
58+
if (flags.debug) {
59+
log(`${GRAY}> ${cmd}${RESET}`)
60+
}
61+
62+
const output = execSync(cmd, { encoding: 'utf8', stdio: 'pipe' }).toString().trim()
63+
64+
if (flags.debug) {
65+
log(output)
66+
}
67+
68+
return output
69+
}
70+
71+
// Start an operation and show a spinner until it reports as passing or failing.
72+
function start (title) {
73+
current = title
74+
75+
spin(0)
76+
}
77+
78+
// Show a spinner for the current operation.
79+
function spin (index) {
80+
if (flags.debug) return
81+
82+
print(`\r${CYAN}${frames[index]}${RESET} ${BOLD}${current}${RESET}`)
83+
84+
timer = setTimeout(spin, 80, index === frames.length - 1 ? 0 : index + 1)
85+
}
86+
87+
// Finish the current operation as passing.
88+
function pass (result) {
89+
if (!current) return
90+
91+
clearTimeout(timer)
92+
93+
if (!flags.debug) {
94+
print(`\r${GREEN}${RESET} ${BOLD}${current}${RESET}`)
95+
96+
if (result) {
97+
print(`: ${BOLD}${CYAN}${result}${RESET}`)
98+
}
99+
100+
print('\n')
101+
}
102+
103+
current = undefined
104+
}
105+
106+
// Finish the current operation as failing.
107+
function fail (err) {
108+
if (!current) return
109+
110+
clearTimeout(timer)
111+
112+
if (!flags.debug) {
113+
print(`\r${RED}${RESET} ${BOLD}${current}${RESET}\n`)
114+
}
115+
116+
current = undefined
117+
118+
throw err
119+
}
120+
121+
// Parse CLI arguments into parameters and flags.
122+
function parse () {
123+
const args = process.argv.slice(2)
124+
const params = []
125+
const flags = {}
126+
127+
for (const arg of args) {
128+
if (arg.startsWith('-')) {
129+
const name = arg.replace(/^-+/, '')
130+
flags[name] = true
131+
} else {
132+
params.push(arg)
133+
}
134+
}
135+
136+
return { params, flags }
49137
}
50138

51-
module.exports = { capture, checkpoint, error, exit, fatal, log, success, run, whisper }
139+
module.exports = {
140+
capture,
141+
checkpoint,
142+
fail,
143+
fatal,
144+
flags,
145+
log,
146+
params,
147+
pass,
148+
run,
149+
start
150+
}

scripts/release/notes.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict'
2+
3+
const fs = require('fs')
4+
const os = require('os')
5+
const path = require('path')
6+
const { capture, success, run } = require('./helpers/terminal')
7+
const pkg = require('../../package.json')
8+
9+
const version = pkg.version
10+
const tag = `v${version}`
11+
const major = version.split('.')[0]
12+
const body = capture(`gh pr view ${tag}-proposal --json body --jq '.body'`)
13+
const args = process.argv.slice(2)
14+
const flags = []
15+
const folder = path.join(os.tmpdir(), 'release_notes')
16+
const file = path.join(folder, `${tag}.md`)
17+
18+
if (args.includes('--latest')) {
19+
flags.push('--latest')
20+
}
21+
22+
if (version.includes('-')) {
23+
flags.push('--prerelease')
24+
}
25+
26+
fs.mkdirSync(folder, { recursive: true })
27+
fs.writeFileSync(file, body)
28+
29+
run(`gh release create ${tag} --target v${major}.x --title ${version} -F ${file} ${flags.join(' ')}`)
30+
31+
success(`Release notes published for ${version}.`)

0 commit comments

Comments
 (0)