Skip to content

Commit fbcd3e8

Browse files
committed
fix: Merger main into release feature branch
2 parents fbdc36b + a26d6ee commit fbcd3e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+5225
-282
lines changed

.github/scripts/change-log-helper.js

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
const fs = require('fs');
2+
const readline = require('readline');
3+
4+
const { logger } = require('../../src/services/messaging/logging');
5+
6+
const defaultVersionRegex = /(\d+)\.(\d+)\.(\d+)/;
7+
const defaultDateRegex = /\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/;
8+
const cliCoreChangelogFile = 'CHANGES.md';
9+
const oaiChangelogFile = 'OAI_CHANGES.md';
10+
11+
class ChangeLogHelper {
12+
constructor(
13+
cliCoreChangelogFilename = cliCoreChangelogFile,
14+
oaiChangelogFilename = oaiChangelogFile,
15+
versionRegex = defaultVersionRegex,
16+
dateRegex = defaultDateRegex,
17+
) {
18+
this.versionRegex = versionRegex;
19+
this.dateRegex = dateRegex;
20+
this.cliCoreChangelogFilename = cliCoreChangelogFilename;
21+
this.oaiChangelogFilename = oaiChangelogFilename;
22+
this.logger = logger;
23+
}
24+
25+
async getAllReleaseVersionsFromGivenDate(date) {
26+
this.logger.info(`Started detecting the versions from the date: ${date}`);
27+
const versions = [];
28+
const readLine = await this.getReadLiner(this.oaiChangelogFilename);
29+
for await (const line of readLine) {
30+
const currentDate = this.dateRegex.exec(line);
31+
if (currentDate) {
32+
const version = this.versionRegex.exec(line);
33+
if (version) {
34+
versions.push(version[0]);
35+
}
36+
if (currentDate[0] <= date) {
37+
break;
38+
}
39+
}
40+
}
41+
this.logger.info(`Detected Versions: ${versions}`);
42+
return versions;
43+
}
44+
45+
async getLatestChangelogGeneratedDate() {
46+
this.logger.info('Started detecting the latest date in cli core changelog');
47+
let latestDate;
48+
const readLine = await this.getReadLiner(this.cliCoreChangelogFilename);
49+
for await (const line of readLine) {
50+
latestDate = this.dateRegex.exec(line);
51+
if (latestDate) {
52+
latestDate = latestDate[0];
53+
this.logger.info(`Detected the latest Date: ${latestDate}`);
54+
break;
55+
}
56+
}
57+
return latestDate;
58+
}
59+
60+
async getChangesAfterGivenDate(date) {
61+
this.logger.info(`Started getting the changelog from given date: ${date}`);
62+
let readLines = false;
63+
let fileData = '';
64+
const readLine = await this.getReadLiner(this.oaiChangelogFilename);
65+
for await (const line of readLine) {
66+
const currentDate = this.dateRegex.exec(line);
67+
if (currentDate) {
68+
if (currentDate[0] > date) {
69+
this.logger.info('Reading the lines');
70+
readLines = true;
71+
} else {
72+
this.logger.info(`Changes from OpenAPI specs: ${fileData}`);
73+
break;
74+
}
75+
} else if (readLines) {
76+
fileData += `${line}\n`;
77+
}
78+
}
79+
return fileData;
80+
}
81+
82+
async appendChangesToChangelog() {
83+
this.logger.info('Started appendChangesToChangelog');
84+
try {
85+
const latestDate = await this.getLatestChangelogGeneratedDate(); // changes.md
86+
if (latestDate) {
87+
const changeLog = await this.getChangesAfterGivenDate(latestDate); // oai_changes.md
88+
if (changeLog) {
89+
this.logger.info('Updating the CHANGES.md');
90+
const data = fs.readFileSync(this.cliCoreChangelogFilename);
91+
if (data.toString().includes(changeLog)) {
92+
this.logger.info(`Provided changes are already in cli core changeLog: ${changeLog}`);
93+
return;
94+
}
95+
const fd = fs.openSync(this.cliCoreChangelogFilename, 'w+');
96+
const insert = Buffer.from(changeLog);
97+
fs.writeSync(fd, insert, 0, insert.length, 0);
98+
fs.writeSync(fd, data, 0, data.length, insert.length);
99+
fs.close(fd, (err) => {
100+
if (err) throw err;
101+
});
102+
fs.writeFileSync('changeLog.md', changeLog);
103+
}
104+
}
105+
} catch (error) {
106+
this.logger.error(`Error while updating the changelog: ${error.message}`);
107+
throw new Error(error);
108+
}
109+
}
110+
111+
async getReadLiner(filename) {
112+
if (!fs.existsSync(filename)) {
113+
throw new Error(`File not found: ${filename}`);
114+
}
115+
const fileStream = fs.createReadStream(filename);
116+
return readline.createInterface({
117+
input: fileStream,
118+
});
119+
}
120+
}
121+
module.exports = {
122+
ChangeLogHelper,
123+
};

.github/scripts/get-version-type.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* eslint-disable no-console */
2+
const { ChangeLogHelper } = require('./change-log-helper');
3+
4+
const ch = new ChangeLogHelper();
5+
6+
const getVersionType = async () => {
7+
const latestDate = await ch.getLatestChangelogGeneratedDate();
8+
const versions = await ch.getAllReleaseVersionsFromGivenDate(latestDate);
9+
if (versions.length >= 2) {
10+
const version1 = versions[0].split('.');
11+
const version2 = versions[versions.length - 1].split('.');
12+
for (let i = 0; i < 3; i++) {
13+
if (version1[i] !== version2[i]) return i;
14+
}
15+
}
16+
return -1;
17+
};
18+
(async () => {
19+
console.log(await getVersionType());
20+
})();
21+
module.exports = {
22+
getVersionType,
23+
};

.github/scripts/trigger-workflow.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const core = require('@actions/core');
2+
const { Octokit } = require('@octokit/rest');
3+
4+
/**
5+
* Functionality from benc-uk/workflow-dispatch.
6+
* Link: https://github.com/benc-uk/workflow-dispatch
7+
*/
8+
const triggerWorkflow = async () => {
9+
try {
10+
const octokit = new Octokit({
11+
auth: process.env.REPO_ACCESS_TOKEN,
12+
});
13+
const workflowRef = process.env.WORKFLOW_NAME;
14+
const ref = process.env.BRANCH_NAME;
15+
const [owner, repo] = process.env.REPO_NAME ? process.env.REPO_NAME.split('/') : [null, null];
16+
17+
// Decode inputs, this MUST be a valid JSON string
18+
let inputs = {};
19+
const inputsJson = process.env.INPUTS;
20+
if (inputsJson) {
21+
inputs = JSON.parse(inputsJson);
22+
}
23+
24+
const workflow = await octokit.rest.actions.getWorkflow({
25+
owner,
26+
repo,
27+
workflow_id: workflowRef,
28+
});
29+
30+
core.info(`Workflow id is: ${workflow.data.id}`);
31+
32+
const dispatchResp = await octokit.rest.actions.createWorkflowDispatch({
33+
owner,
34+
repo,
35+
workflow_id: workflow.data.id,
36+
ref,
37+
inputs,
38+
});
39+
core.info(`API response status: ${dispatchResp.status}.`);
40+
} catch (error) {
41+
core.setFailed(error.message);
42+
}
43+
};
44+
45+
module.exports = {
46+
triggerWorkflow,
47+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/sh
2+
echo "Copying api-definitions"
3+
cp -R ~/oai_definitions/json/. src/services/twilio-api/
4+
echo "Running update changelog script"
5+
node .github/scripts/update-change-log.js
6+
changeLog=''
7+
versionType=-1
8+
if [ -f changeLog.md ]; then
9+
changeLog=$(cat changeLog.md)
10+
rm -rf changeLog.md
11+
if [ "$changeLog" != '' ]; then
12+
changeLog="${changeLog//'%'/'%25'}"
13+
changeLog="${changeLog//$'\n'/'%0A'}"
14+
changeLog="${changeLog//$'\r'/'%0D'}"
15+
versionType=$(node .github/scripts/get-version-type.js | tail -n -1)
16+
fi
17+
fi
18+
echo "Changelog: $changeLog"
19+
echo "Version type: $versionType"
20+
rm -rf OAI_CHANGES.md
21+
echo "Git configurations"
22+
git config --global user.email "[email protected]"
23+
git config --global user.name "twilio-dx"
24+
branch=$(git branch --show-current)
25+
echo "Current branch: $branch"
26+
git add -A
27+
if [ -n "$(git status --porcelain)" ]; then
28+
echo "There are changes to commit.";
29+
commitMessage=''
30+
if [ "$versionType" == 0 ] || [ "$versionType" == 1 ]
31+
then
32+
commitMessage='oaiFeat: Updated api definitions'
33+
elif [ "$versionType" == 2 ]
34+
then
35+
commitMessage='oaiFix: Updated api definitions'
36+
else
37+
echo "Invalid versionType: $versionType";
38+
exit
39+
fi
40+
echo "Commit message:$commitMessage"
41+
git commit -m "$commitMessage"
42+
git push origin "$branch"
43+
else
44+
echo "No changes to commit";
45+
fi

.github/scripts/update-change-log.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { ChangeLogHelper } = require('./change-log-helper');
2+
3+
const ch = new ChangeLogHelper();
4+
5+
const updateChangeLog = async () => {
6+
return ch.appendChangesToChangelog();
7+
};
8+
(async () => {
9+
await updateChangeLog();
10+
})();

.github/scripts/update-release.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const core = require('@actions/core');
2+
const { GitHub } = require('@actions/github');
3+
4+
/**
5+
* Functionality from tubone24/update_release.
6+
* Link: https://github.com/tubone24/update_release
7+
*/
8+
const updateRelease = async () => {
9+
try {
10+
const github = new GitHub(process.env.REPO_ACCESS_TOKEN);
11+
const [owner, repo] = process.env.REPO_NAME ? process.env.REPO_NAME.split('/') : [null, null];
12+
const tag = process.env.TAG_NAME;
13+
const getReleaseResponse = await github.repos.getReleaseByTag({
14+
owner,
15+
repo,
16+
tag,
17+
});
18+
19+
const {
20+
data: {
21+
id: oldReleaseId,
22+
html_url: oldHtmlUrl,
23+
upload_url: oldUploadUrl,
24+
body: oldBody,
25+
draft: oldDraft,
26+
name: oldName,
27+
prerelease: oldPrerelease,
28+
},
29+
} = getReleaseResponse;
30+
31+
core.info(`Got release info: '${oldReleaseId}', ${oldName}, '${oldHtmlUrl}', '${oldUploadUrl},'`);
32+
core.info(`Body: ${oldBody}`);
33+
core.info(`Draft: ${oldDraft}, Prerelease: ${oldPrerelease}`);
34+
35+
const newBody = process.env.RELEASE_BODY;
36+
const newPrerelease = process.env.PRE_RELEASE;
37+
38+
let body;
39+
if (newBody === '') {
40+
body = oldBody;
41+
} else {
42+
body = `${oldBody}\n${newBody}`;
43+
}
44+
45+
let prerelease;
46+
if (newPrerelease !== '' && Boolean(newPrerelease)) {
47+
prerelease = newPrerelease === 'true';
48+
} else {
49+
prerelease = oldPrerelease;
50+
}
51+
52+
await github.repos.updateRelease({
53+
owner,
54+
release_id: oldReleaseId,
55+
repo,
56+
body,
57+
name: oldName,
58+
draft: oldDraft,
59+
prerelease,
60+
});
61+
62+
core.info(`Updated release with body: ${body}`);
63+
} catch (error) {
64+
core.setFailed(error.message);
65+
}
66+
};
67+
68+
module.exports = {
69+
updateRelease,
70+
};

.github/workflows/cli-core-test.yml

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Cli Core Tests
2+
on:
3+
push:
4+
branches: [ main ]
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
node-version: [16.x, 14.x, 10.x]
14+
steps:
15+
- name: Checkout cli core repo
16+
uses: actions/checkout@v2
17+
- run: npm install
18+
- name: Use Node.js ${{ matrix.node-version }}
19+
uses: actions/setup-node@v2
20+
with:
21+
node-version: ${{ matrix.node-version }}
22+
cache: 'npm'
23+
- name: Run tests
24+
run: npm test
25+
sonarcloud:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v2
29+
with:
30+
# Disabling shallow clone is recommended for improving relevancy of reporting
31+
fetch-depth: 0
32+
- name: SonarCloud Scan
33+
uses: sonarsource/sonarcloud-github-action@master
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
37+
notify-complete-fail:
38+
if: ${{ failure() || cancelled() }}
39+
needs: [ test, sonarcloud ]
40+
name: Notify Test Failed
41+
runs-on: ubuntu-latest
42+
steps:
43+
- uses: actions/checkout@v2
44+
- name: Slack Notification
45+
uses: rtCamp/action-slack-notify@v2
46+
env:
47+
SLACK_WEBHOOK: ${{ secrets.ALERT_SLACK_WEB_HOOK }}
48+
SLACK_COLOR: ${{ job.status }}
49+
SLACK_USERNAME: CLI Github Actions
50+
SLACK_MSG_AUTHOR: twilio-dx
51+
SLACK_ICON_EMOJI: ':github:'
52+
SLACK_TITLE: "Twilio Cli Core"
53+
SLACK_MESSAGE: 'Cli core tests failed'
54+
MSG_MINIMAL: actions url
55+
SLACK_FOOTER: Posted automatically using GitHub Actions

0 commit comments

Comments
 (0)