forked from newrelic/newrelic-quickstarts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelease.ts
145 lines (123 loc) · 4.2 KB
/
release.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import 'dotenv/config';
import { input, password } from '@inquirer/prompts';
import confirm from '@inquirer/confirm';
import select from '@inquirer/select';
import { appendFileSync } from 'node:fs';
import { createValidateQuickstarts } from './create_validate_pr_quickstarts';
import { createValidateDataSources } from './create-validate-data-sources';
import { generatePrUrl } from './lib/github-api-helpers';
import { setDashboardsRequiredDataSources } from './set-dashboards-required-datasources';
import { setAlertPoliciesRequiredDataSources } from './set-alert-policy-required-datasources';
type Environment = 'local' | 'staging' | 'us' | 'eu';
type Context = {
ENVIRONMENT: Environment;
GH_TOKEN: string;
NR_API_TOKEN: string;
PR_NUMBER: string | number;
PR_URL: string;
API_ENDPOINT: string;
};
const API_ENDPOINTS: Record<Environment, string> = {
local: 'https://localhost.newrelic.com:3100/graphql',
staging: 'https://staging-api.newrelic.com/graphql',
us: 'https://api.newrelic.com/graphql',
eu: 'https://api.eu.newrelic.com/graphql',
};
const divider = () => console.log('―――――――――――――――――――――――――――――');
const stepMessage = (message: string) => {
divider();
console.log(message);
divider();
};
const bootstrap = async (): Promise<Context> => {
const ENVIRONMENT = await select<Environment>({
message: 'Select an environment to target.',
choices: [
{ name: 'Local', value: 'local' },
{ name: 'Staging', value: 'staging' },
{ name: 'US Production', value: 'us' },
{ name: 'EU Production', value: 'eu' },
],
});
let GH_TOKEN = process.env.GH_TOKEN;
let NR_API_TOKEN = process.env[`NR_API_TOKEN_${ENVIRONMENT.toUpperCase()}`];
if (ENVIRONMENT === 'local') {
// Local env should use staging API token
NR_API_TOKEN = process.env['NR_API_TOKEN_STAGING'];
// Allow self-signed certs against localhost
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}
if (!NR_API_TOKEN) {
stepMessage(`No API key found for ${ENVIRONMENT}.`);
NR_API_TOKEN = await password({
message: `What is your NR API key for ${ENVIRONMENT}?`,
});
appendFileSync(
'.env',
`\nNR_API_TOKEN_${ENVIRONMENT.toUpperCase()}=${NR_API_TOKEN}`
);
console.log(
`Your NR API key for ${ENVIRONMENT} has been saved to the .env file. Do not commit this file.`
);
}
if (!GH_TOKEN) {
stepMessage(
"No GitHub token found. You may experience rate-limiting from the GitHub API if you don't enter one."
);
GH_TOKEN = await password({
message: 'What is your GitHub token? (optional)',
});
if (GH_TOKEN?.length) {
appendFileSync('.env', `\nGH_TOKEN=${GH_TOKEN}`);
console.log(
'Your GitHub token has been saved to the .env file. Do not commit this file.'
);
}
}
divider();
const PR_NUMBER = await input({
message:
'What is the PR number for the merge of the release branch into main?',
});
divider();
const PR_URL = generatePrUrl(PR_NUMBER);
// Set required env vars that can't be passed into function calls
process.env.NR_API_URL = API_ENDPOINTS[ENVIRONMENT];
process.env.NR_API_TOKEN = NR_API_TOKEN;
return {
ENVIRONMENT,
GH_TOKEN,
NR_API_TOKEN,
PR_NUMBER,
PR_URL,
API_ENDPOINT: API_ENDPOINTS[ENVIRONMENT],
};
};
const main = async () => {
const { ENVIRONMENT, GH_TOKEN, PR_URL } = await bootstrap();
stepMessage(`Performing dry run release to ${ENVIRONMENT}...`);
// Dry run
await runTasks(PR_URL, GH_TOKEN, true);
const shouldContinue = await confirm({
message: 'Dry run was successful. Proceed to deploy?',
});
if (shouldContinue) {
stepMessage(`🚀 Releasing to ${ENVIRONMENT}!`);
// Real deploy
runTasks(PR_URL, GH_TOKEN, false);
} else {
console.log('Aborting.');
process.exit(0);
}
};
const runTasks = async (url: string, token: string, dryRun = true) => {
await createValidateDataSources(url, token, dryRun);
await createValidateQuickstarts(url, token, dryRun);
if (!dryRun) {
await setDashboardsRequiredDataSources(url, token);
await setAlertPoliciesRequiredDataSources(url, token);
}
};
if (require.main === module) {
main();
}