newrelic 7.0.2 → 7.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NEWS.md CHANGED
@@ -1,6 +1,67 @@
1
+ ### v7.1.3 (2021-03-09)
2
+
3
+ * Bumped @grpc/grpc-js to ^1.2.7.
4
+
5
+ * Removed index-bad-config test which tested a no-longer possible use-case.
6
+
7
+ * Removed license-key test logic from serverless-harvest test.
8
+
9
+ Serverless mode does not require a license key as data transfer is handled by the integration.
10
+
11
+ * Added support metric to be able to track usage of cert bundle via usage of custom certificates.
12
+
13
+ * Removed requirement to configure application name when running in AWS Lambda (serverless mode).
14
+
15
+ Application name is not currently leveraged by New Relic for Lambda invocations. The agent now defaults the application name in serverless mode to remove the requirement of end-user configuration while handling cases if it were to be leveraged in the future.
16
+
17
+ * Stopped binding/propagating segments via `setImmediate` for ended transactions.
18
+
19
+ * Fixed bug where agent would attempt to call the 'preconnect' endpoint on the redirect host returned by the previous 'preconnect' call when reconnecting to the New Relic servers.
20
+
21
+ The 'preconnect' calls will now always use the original agent configuration value. Subsequent endpoints (connect, harvest endpoints, etc.) will continue to leverage the new redirect host value returned by 'preconnect.' The original config values are no-longer overridden.
22
+
23
+ * Fixed issue where a call to `transaction.acceptDistributedTraceHeaders` would throw an error when the `headers` parameter is a string.
24
+
25
+ * Improved clarity of logging between 'no log file' or disabled agent startup issues.
26
+
27
+ * Logs no-config file error to initialized logger (stdout) in addition to existing console.error() logging.
28
+ * Adds specific message to no config file separate from being disabled.
29
+
30
+ * Removed aws-sdk versioned test filtering.
31
+
32
+ * Removed unused Travis CI scripts.
33
+
34
+ ### v7.1.2 (2021-02-24)
35
+
36
+ * Fixed bug where the agent failed to reconnect to Infinite Tracing gRPC streams on Status OK at higher log levels.
37
+
38
+ Node streams require all data be consumed for the end/status events to fire. We were only reading data at lower log levels where we'd use/log the data. This resulted in a failure to reconnect and 'ERR_STREAM_WRITE_AFTER_END' errors. The agent now always listens to the 'data' event, even if not logging, and will also reconnect (with 15 second delay) on any 'ERR_STREAM_WRITE_AFTER_END' error.
39
+
40
+ * Removed initial harvest send() call on streaming span event aggregator to prevent warning in logs.
41
+
42
+ * Bumped @newrelic/aws-sdk to ^3.1.0.
43
+
44
+ ### v7.1.1 (2021-02-01)
45
+
46
+ * Upgrade @grpc/grpc-js to v1.2.5 to fix non-propagation of internal http2 errors
47
+ Now allows minor and patch auto-updates.
48
+
49
+ * Added workflow for publishing to npm when a v* tag is pushed to the repo.
50
+
51
+ * Fixes resolveMx test by using example.com for a valid exchange.
52
+
53
+ ### 7.1.0 (2021-01-05):
54
+
55
+ * Fixed SQL traces being generated with invalid ID.
56
+ * Fixed log message for minimum supported Node.js version.
57
+ * Added Fastify v3 support.
58
+ * Fixed empty log message for Infinite Tracing connections.
59
+ * Upgraded grpc version.
60
+ * Fixed bug that prevented users from changing Infinite Tracing queue size.
61
+
1
62
  ### 7.0.2 (2020-12-01):
2
63
 
3
- * Fixes a bug where the `http.statusCode` attribute was not being captured for an async invoked lambda.
64
+ * Fixed a bug where the `http.statusCode` attribute was not being captured for an async invoked lambda.
4
65
  * Fixed typos in code comments, documentation, and debugging logger messages.
5
66
  Thank you @TysonAndre for the contribution.
6
67
 
@@ -35,6 +35,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
35
35
 
36
36
  * [@newrelic/proxy](#newrelicproxy)
37
37
  * [@newrelic/test-utilities](#newrelictest-utilities)
38
+ * [@octokit/rest](#octokitrest)
38
39
  * [JSV](#JSV)
39
40
  * [architect](#architect)
40
41
  * [benchmark](#benchmark)
@@ -73,7 +74,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
73
74
 
74
75
  ### @grpc/grpc-js
75
76
 
76
- This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.2.0](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.2.0)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.2.0/LICENSE):
77
+ This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.2.5](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.2.5)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.2.5/LICENSE):
77
78
 
78
79
  ```
79
80
  Apache License
@@ -491,7 +492,7 @@ This product includes source derived from [@grpc/proto-loader](https://github.co
491
492
 
492
493
  ### @newrelic/aws-sdk
493
494
 
494
- This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v3.0.0](https://github.com/newrelic/node-newrelic-aws-sdk/tree/v3.0.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-aws-sdk/blob/v3.0.0/LICENSE):
495
+ This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v3.1.0](https://github.com/newrelic/node-newrelic-aws-sdk/tree/v3.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-aws-sdk/blob/v3.1.0/LICENSE):
495
496
 
496
497
  ```
497
498
  Apache License
@@ -1207,11 +1208,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1207
1208
  This product includes source derived from [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) ([v4.0.0](https://github.com/TooTallNate/node-https-proxy-agent/tree/v4.0.0)), distributed under the [MIT License](https://github.com/TooTallNate/node-https-proxy-agent/blob/v4.0.0/README.md):
1208
1209
 
1209
1210
  ```
1210
- MIT License Copyright (c) <year> <copyright holders>
1211
+ MIT License
1212
+
1213
+ Copyright (c) <year> <copyright holders>
1211
1214
 
1212
1215
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1213
1216
 
1214
- The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
1217
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1215
1218
 
1216
1219
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1217
1220
  ```
@@ -1534,11 +1537,13 @@ This product includes source derived from [@newrelic/native-metrics](https://git
1534
1537
  This product includes source derived from [@newrelic/proxy](https://github.com/newrelic/proxy) ([v2.0.0](https://github.com/newrelic/proxy/tree/v2.0.0)), distributed under the [MIT License](https://github.com/newrelic/proxy/blob/v2.0.0/README.md):
1535
1538
 
1536
1539
  ```
1537
- MIT License Copyright (c) <year> <copyright holders>
1540
+ MIT License
1541
+
1542
+ Copyright (c) <year> <copyright holders>
1538
1543
 
1539
1544
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1540
1545
 
1541
- The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
1546
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1542
1547
 
1543
1548
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1544
1549
  ```
@@ -1752,23 +1757,41 @@ This product includes source derived from [@newrelic/test-utilities](https://git
1752
1757
 
1753
1758
  ```
1754
1759
 
1755
- ### JSV
1760
+ ### @octokit/rest
1756
1761
 
1757
- This product includes source derived from [JSV](https://github.com/garycourt/JSV) ([v4.0.2](https://github.com/garycourt/JSV/tree/v4.0.2)), distributed under the [FreeBSD License](https://github.com/garycourt/JSV/tree/v4.0.2#license):
1762
+ This product includes source derived from [@octokit/rest](https://github.com/octokit/rest.js) ([v18.0.15](https://github.com/octokit/rest.js/tree/v18.0.15)), distributed under the [MIT License](https://github.com/octokit/rest.js/blob/v18.0.15/LICENSE):
1758
1763
 
1759
1764
  ```
1760
- Copyright 2010 Gary Court. All rights reserved.
1765
+ The MIT License
1766
+
1767
+ Copyright (c) 2012 Cloud9 IDE, Inc. (Mike de Boer)
1768
+ Copyright (c) 2017-2018 Octokit contributors
1769
+
1770
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1771
+ of this software and associated documentation files (the "Software"), to deal
1772
+ in the Software without restriction, including without limitation the rights
1773
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1774
+ copies of the Software, and to permit persons to whom the Software is
1775
+ furnished to do so, subject to the following conditions:
1776
+
1777
+ The above copyright notice and this permission notice shall be included in
1778
+ all copies or substantial portions of the Software.
1761
1779
 
1762
- Redistribution and use in source and binary forms, with or without modification, are
1763
- permitted provided that the following conditions are met:
1780
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1781
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1782
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1783
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1784
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1785
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1786
+ THE SOFTWARE.
1764
1787
 
1765
- 1. Redistributions of source code must retain the above copyright notice, this list of
1766
- conditions and the following disclaimer.
1788
+ ```
1767
1789
 
1768
- 2. Redistributions in binary form must reproduce the above copyright notice, this list
1769
- of conditions and the following disclaimer in the documentation and/or other materials
1770
- provided with the distribution.
1790
+ ### JSV
1771
1791
 
1792
+ This product includes source derived from [JSV](https://github.com/garycourt/JSV) ([v4.0.2](https://github.com/garycourt/JSV/tree/v4.0.2)), distributed under the [FreeBSD License](https://github.com/garycourt/JSV/tree/v4.0.2#license):
1793
+
1794
+ ```
1772
1795
  THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED
1773
1796
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1774
1797
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR
@@ -1997,11 +2020,13 @@ SOFTWARE.
1997
2020
  This product includes source derived from [generic-pool](https://github.com/coopernurse/node-pool) ([v3.7.1](https://github.com/coopernurse/node-pool/tree/v3.7.1)), distributed under the [MIT License](https://github.com/coopernurse/node-pool/blob/v3.7.1/README.md):
1998
2021
 
1999
2022
  ```
2000
- MIT License Copyright (c) <year> <copyright holders>
2023
+ MIT License
2024
+
2025
+ Copyright (c) <year> <copyright holders>
2001
2026
 
2002
2027
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2003
2028
 
2004
- The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
2029
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
2005
2030
 
2006
2031
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2007
2032
  ```
@@ -2614,11 +2639,13 @@ IN THE SOFTWARE.
2614
2639
  This product includes source derived from [redis](https://github.com/mranney/node_redis) ([v1.0.0](https://github.com/mranney/node_redis/tree/v1.0.0)), distributed under the [MIT License](https://github.com/mranney/node_redis/blob/v1.0.0/README.md):
2615
2640
 
2616
2641
  ```
2617
- MIT License Copyright (c) <year> <copyright holders>
2642
+ MIT License
2643
+
2644
+ Copyright (c) <year> <copyright holders>
2618
2645
 
2619
2646
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2620
2647
 
2621
- The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
2648
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
2622
2649
 
2623
2650
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2624
2651
  ```
@@ -0,0 +1,74 @@
1
+ 'use strict'
2
+
3
+ const Github = require('./github')
4
+
5
+ const SUCCESS_MSG = '*** [OK] ***'
6
+
7
+ const formatRun = (run) => {
8
+ return {
9
+ name: run.name,
10
+ repository: run.repository.name,
11
+ repoOwner: run.repository.owner.login,
12
+ branch: run.head_branch,
13
+ status: run.status,
14
+ url: run.url,
15
+ workflow_id: run.workflow_id,
16
+ event: run.event
17
+ }
18
+ }
19
+
20
+ async function checkWorkflowRun(repoOwner, branch) {
21
+ const github = new Github(repoOwner)
22
+
23
+ try {
24
+ const results = {
25
+ ci: false,
26
+ smokeTest: false
27
+ }
28
+
29
+ const latestRun = await github.getLatestWorkflowRun('ci-workflow.yml', branch)
30
+
31
+ if (latestRun === undefined) {
32
+ console.log('No ci workflow run found.')
33
+ } else {
34
+ console.log('CI workflow run details: ', JSON.stringify(formatRun(latestRun)))
35
+ if (latestRun.status === 'completed' && latestRun.conclusion === 'success') {
36
+ results.ci = true
37
+ }
38
+ }
39
+
40
+ const latestSmokeTestRun = await github.getLatestWorkflowRun('smoke-test-workflow.yml', branch)
41
+
42
+ if (latestSmokeTestRun === undefined) {
43
+ console.log('No smoke test workflow run found.')
44
+ } else {
45
+ console.log('Smoke-test workflow run details: ', JSON.stringify(formatRun(latestSmokeTestRun)))
46
+
47
+ if (latestSmokeTestRun.status === 'completed' && latestSmokeTestRun.conclusion === 'success') {
48
+ results.smokeTest = true
49
+ }
50
+ }
51
+
52
+ if (results.ci && results.smokeTest) {
53
+ console.log(SUCCESS_MSG)
54
+ console.log('Latest ci and smoke-test runs were successful!')
55
+ return true
56
+ }
57
+
58
+ if (!results.ci) {
59
+ console.log('Latest ci workflow run result was not \'completed\' and \'success\'.')
60
+ }
61
+
62
+ if (!results.smokeTest) {
63
+ console.log('Latest smoke-test workflow run result was not \'completed\' and \'success\'.')
64
+ }
65
+
66
+ return false
67
+ } catch (err) {
68
+ console.error(err)
69
+
70
+ return false
71
+ }
72
+ }
73
+
74
+ module.exports = checkWorkflowRun
@@ -0,0 +1,109 @@
1
+ 'use strict'
2
+
3
+ const fs = require('fs')
4
+ const {program} = require('commander')
5
+
6
+ const Github = require('./github')
7
+ const { indexOf } = require('benchmark')
8
+
9
+ const DEFAULT_FILE_NAME = 'NEWS.md'
10
+ /** e.g. v7.2.1 */
11
+ const TAG_VALID_REGEX = /v\d+\.\d+\.\d+/
12
+
13
+ program.requiredOption('--tag <tag>', 'tag name to create GitHub release for')
14
+ program.option('--repo-owner <repoOwner>', 'repository owner', 'newrelic')
15
+ program.option('--release-notes-file <releaseNotesFile>', 'path to release notes file', DEFAULT_FILE_NAME)
16
+ program.option('-f --force', 'bypass validation')
17
+
18
+ async function createRelease() {
19
+ // Parse commandline options inputs
20
+ program.parse()
21
+
22
+ const options = program.opts()
23
+
24
+ console.log('Script running with following options: ', JSON.stringify(options))
25
+
26
+ const github = new Github(options.repoOwner)
27
+
28
+ try {
29
+ const tagName = options.tag.replace('refs/tags/', '')
30
+ console.log('Using tag name: ', tagName)
31
+
32
+ logStep('Validation')
33
+ if (options.force) {
34
+ console.log('--force set. Skipping validation logic')
35
+ }
36
+
37
+ if (!options.force && !TAG_VALID_REGEX.exec(tagName)) {
38
+ console.log('Tag arg invalid (%s). Valid tags in form: v#.#.# (e.g. v7.2.1)', tagName)
39
+ stopOnError()
40
+ }
41
+
42
+ logStep('Get Release Notes from File')
43
+ const body = await getReleaseNotes(tagName, options.releaseNotesFile)
44
+
45
+ logStep('Create Release')
46
+ await github.createRelease(tagName, tagName, body)
47
+
48
+ console.log('*** Full Run Successful ***')
49
+ } catch (err) {
50
+ if (err.status && err.status === 404) {
51
+ console.log('404 status error detected. For octokit, this may mean insuffient permissions.')
52
+ console.log('Ensure you have a valid GITHUB_TOKEN set in your env vars.')
53
+ }
54
+
55
+ stopOnError(err)
56
+ }
57
+ }
58
+
59
+ async function getReleaseNotes(tagName, releaseNotesFile) {
60
+ console.log('Retrieving release notes from file: ', releaseNotesFile)
61
+
62
+ const data = await readReleaseNoteFile(releaseNotesFile)
63
+
64
+ const currentVersionHeader = `### ${tagName}`
65
+ if (data.indexOf(currentVersionHeader) !== 0) {
66
+ throw new Error(`Current tag (${currentVersionHeader}) not first line of release notes.`)
67
+ }
68
+
69
+ const sections = data.split('### ', 2)
70
+ if (sections.length !== 2) {
71
+ throw new Error('Did not split into multiple sections. Double check notes format.')
72
+ }
73
+
74
+ const tagSection = sections[1]
75
+ // e.g. v7.1.2 (2021-02-24)\n\n
76
+ const headingRegex = /^v\d+\.\d+\.\d+ \(\d{4}-\d{2}-\d{2}\)\n\n/
77
+ const headingRemoved = tagSection.replace(headingRegex, '')
78
+
79
+ return headingRemoved
80
+ }
81
+
82
+ async function readReleaseNoteFile(file) {
83
+ const promise = new Promise((resolve, reject) => {
84
+ fs.readFile(file, 'utf8', function (err, data) {
85
+ if (err) {
86
+ return reject(err)
87
+ }
88
+
89
+ resolve(data)
90
+ })
91
+ })
92
+
93
+ return promise
94
+ }
95
+
96
+ function stopOnError(err) {
97
+ if (err) {
98
+ console.error(err)
99
+ }
100
+
101
+ console.log('Halting execution with exit code: 1')
102
+ process.exit(1)
103
+ }
104
+
105
+ function logStep(step) {
106
+ console.log(`\n ----- [Step]: ${step} -----\n`)
107
+ }
108
+
109
+ createRelease()
@@ -0,0 +1,95 @@
1
+ 'use strict'
2
+
3
+ const {program} = require('commander')
4
+
5
+ const checkWorkflowRun = require('./check-workflow-run')
6
+ const git = require('./git-commands')
7
+
8
+ // Add command line options
9
+ program.option('-b, --branch <branch>', 'release branch', 'main')
10
+ program.option('-o, --repo-owner <repoOwner>', 'repository owner', 'newrelic')
11
+ program.option('-f --force', 'bypass validation')
12
+
13
+ async function createReleaseTag() {
14
+ // Parse commandline options inputs
15
+ program.parse()
16
+
17
+ const options = program.opts()
18
+
19
+ console.log('Script running with following options: ', JSON.stringify(options))
20
+
21
+ const branch = options.branch.replace('refs/heads/', '')
22
+ const repoOwner = options.repoOwner
23
+
24
+ if (options.force) {
25
+ console.log('--force set. Skipping validation logic')
26
+ }
27
+
28
+ try {
29
+ const isValid = options.force || (
30
+ await validateLocalChanges() &&
31
+ await validateCurrentBranch(branch) &&
32
+ await checkWorkflowRun(repoOwner, branch)
33
+ )
34
+
35
+ if (!isValid) {
36
+ process.exit(1)
37
+ }
38
+
39
+ const packagePath = '../package.json'
40
+ console.log('Extracting new version from package.json here: ', )
41
+ const packageInfo = require(packagePath)
42
+
43
+ const version = `v${packageInfo.version}`
44
+ console.log('New version is: ', version)
45
+
46
+ console.log('Creating and pushing tag')
47
+
48
+ await git.createAnnotatedTag(version, version)
49
+ await git.pushTags()
50
+
51
+ console.log('*** Full Run Successful ***')
52
+ } catch (err) {
53
+ console.log(err)
54
+
55
+ process.exit(1)
56
+ }
57
+ }
58
+
59
+ async function validateLocalChanges() {
60
+ try {
61
+ const localChanges = await git.getLocalChanges()
62
+ if (localChanges.length > 0) {
63
+ console.log('Local changes detected: ', localChanges)
64
+ console.log('Please commit to a feature branch or stash changes and then try again.')
65
+ return false
66
+ }
67
+
68
+ return true
69
+ } catch (err) {
70
+ console.error(err)
71
+ return false
72
+ }
73
+ }
74
+
75
+ async function validateCurrentBranch(branch) {
76
+ try {
77
+ const currentBranch = await git.getCurrentBranch()
78
+
79
+ if (branch != currentBranch) {
80
+ console.log(
81
+ 'Current checked-out branch (%s) does not match expected (%s)',
82
+ currentBranch,
83
+ branch
84
+ )
85
+ return false
86
+ }
87
+
88
+ return true
89
+ } catch (err) {
90
+ console.error(err)
91
+ return false
92
+ }
93
+ }
94
+
95
+ createReleaseTag()
@@ -0,0 +1,110 @@
1
+ 'use strict'
2
+
3
+ const { exec } = require('child_process')
4
+
5
+ async function getPushRemotes() {
6
+ const stdout = await execAsPromise('git remote -v')
7
+
8
+ const remotes = stdout.split('\n')
9
+ const processedRemotes = remotes.reduce((remotePairs, currentRemote) => {
10
+ const parts = currentRemote.split('\t')
11
+ if (parts.length < 2) {
12
+ return remotePairs
13
+ }
14
+
15
+ const [name, url] = parts
16
+ if (url.indexOf('(push)') >= 0) {
17
+ remotePairs[name] = url
18
+ }
19
+
20
+ return remotePairs
21
+ }, {})
22
+
23
+ return processedRemotes
24
+ }
25
+
26
+ async function getLocalChanges() {
27
+ const stdout = await execAsPromise('git status --short --porcelain')
28
+ const changes = stdout.split('\n').filter((line) => {
29
+ return line.length > 0
30
+ })
31
+
32
+ return changes
33
+ }
34
+
35
+ async function getCurrentBranch() {
36
+ const stdout = await execAsPromise('git branch --show-current')
37
+ const branch = stdout.trim()
38
+
39
+ return branch
40
+ }
41
+
42
+ async function checkoutNewBranch(name) {
43
+ const stdout = await execAsPromise(`git checkout -b ${name}`)
44
+ const output = stdout.trim()
45
+
46
+ return output
47
+ }
48
+
49
+ async function addAllFiles() {
50
+ const stdout = await execAsPromise(`git add .`)
51
+ const output = stdout.trim()
52
+
53
+ return output
54
+ }
55
+
56
+ async function commit(message) {
57
+ const stdout = await execAsPromise(`git commit -m "${message}"`)
58
+ const output = stdout.trim()
59
+
60
+ return output
61
+ }
62
+
63
+ async function pushToRemote(remote, branchName) {
64
+ const stdout = await execAsPromise(`git push --set-upstream ${remote} ${branchName}`)
65
+ const output = stdout.trim()
66
+
67
+ return output
68
+ }
69
+
70
+ async function createAnnotatedTag(name, message) {
71
+ const stdout = await execAsPromise(`git tag -a ${name} -m ${message}`)
72
+ const output = stdout.trim()
73
+
74
+ return output
75
+ }
76
+
77
+ async function pushTags() {
78
+ const stdout = await execAsPromise('git push --tags')
79
+ const output = stdout.trim()
80
+
81
+ return output
82
+ }
83
+
84
+ function execAsPromise(command) {
85
+ const promise = new Promise((resolve, reject) => {
86
+ console.log(`Executing: '${command}'`)
87
+
88
+ exec(command, (err, stdout) => {
89
+ if (err) {
90
+ return reject(err)
91
+ }
92
+
93
+ resolve(stdout)
94
+ })
95
+ })
96
+
97
+ return promise
98
+ }
99
+
100
+ module.exports = {
101
+ getPushRemotes,
102
+ getLocalChanges,
103
+ getCurrentBranch,
104
+ checkoutNewBranch,
105
+ addAllFiles,
106
+ commit,
107
+ pushToRemote,
108
+ createAnnotatedTag,
109
+ pushTags
110
+ }