forked from twilio/twilio-cli-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Enable GitHub actions. (twilio#150)
* feat: Enable GitHub actions. Changes: 1. Added workflow file 2. Added scripts to update the changelog in cli-core 3. Added the actions to bump the version and release to GitHub * Updated the github email and username * Code refactoring - Removing the unneccesary runs * Added changes to trigger cli workflow with changelog input * Fixing the json issue and added versionType * Changed the naming convention as per the GitHub actions * Update release.yml * Added missing changes * Added pre release tag and some conditions * Refactored the code and addressed the review comments * Added semantic release output to update release job * Update release.yml * Added test case for changeLogHelper * Added test cases for get-version-type * Update release.yml * Added changed to fix the failed test cases in travis * Empty commit for Travis testing * Update package.json * Update release.yml * Added change to publish to npm * Added inputs to homebrew in cli-core * Added npm token in semantic release action. * Added release_feature_branch as prerelease branch Co-authored-by: lakshmiravali <[email protected]>
- Loading branch information
1 parent
5c579b9
commit 002dd1f
Showing
9 changed files
with
636 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
const fs = require('fs'); | ||
const readline = require('readline'); | ||
|
||
const { logger } = require('../../src/services/messaging/logging'); | ||
|
||
const defaultVersionRegex = /(\d+)\.(\d+)\.(\d+)/; | ||
const defaultDateRegex = /\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/; | ||
const cliCoreChangelogFile = 'CHANGES.md'; | ||
const oaiChangelogFile = 'OAI_CHANGES.md'; | ||
|
||
class ChangeLogHelper { | ||
constructor( | ||
cliCoreChangelogFilename = cliCoreChangelogFile, | ||
oaiChangelogFilename = oaiChangelogFile, | ||
versionRegex = defaultVersionRegex, | ||
dateRegex = defaultDateRegex, | ||
) { | ||
this.versionRegex = versionRegex; | ||
this.dateRegex = dateRegex; | ||
this.cliCoreChangelogFilename = cliCoreChangelogFilename; | ||
this.oaiChangelogFilename = oaiChangelogFilename; | ||
this.logger = logger; | ||
} | ||
|
||
async getAllReleaseVersionsFromGivenDate(date) { | ||
this.logger.info(`Started detecting the versions from the date: ${date}`); | ||
const versions = []; | ||
const readLine = await this.getReadLiner(this.oaiChangelogFilename); | ||
for await (const line of readLine) { | ||
const currentDate = this.dateRegex.exec(line); | ||
if (currentDate) { | ||
const version = this.versionRegex.exec(line); | ||
if (version) { | ||
versions.push(version[0]); | ||
} | ||
if (currentDate[0] <= date) { | ||
break; | ||
} | ||
} | ||
} | ||
this.logger.info(`Detected Versions: ${versions}`); | ||
return versions; | ||
} | ||
|
||
async getLatestChangelogGeneratedDate() { | ||
this.logger.info('Started detecting the latest date in cli core changelog'); | ||
let latestDate; | ||
const readLine = await this.getReadLiner(this.cliCoreChangelogFilename); | ||
for await (const line of readLine) { | ||
latestDate = this.dateRegex.exec(line); | ||
if (latestDate) { | ||
latestDate = latestDate[0]; | ||
this.logger.info(`Detected the latest Date: ${latestDate}`); | ||
break; | ||
} | ||
} | ||
return latestDate; | ||
} | ||
|
||
async getChangesAfterGivenDate(date) { | ||
this.logger.info(`Started getting the changelog from given date: ${date}`); | ||
let readLines = false; | ||
let fileData = ''; | ||
const readLine = await this.getReadLiner(this.oaiChangelogFilename); | ||
for await (const line of readLine) { | ||
const currentDate = this.dateRegex.exec(line); | ||
if (currentDate) { | ||
if (currentDate[0] > date) { | ||
this.logger.info('Reading the lines'); | ||
readLines = true; | ||
} else { | ||
this.logger.info(`Changes from OpenAPI specs: ${fileData}`); | ||
break; | ||
} | ||
} else if (readLines) { | ||
fileData += `${line}\n`; | ||
} | ||
} | ||
return fileData; | ||
} | ||
|
||
async appendChangesToChangelog() { | ||
this.logger.info('Started appendChangesToChangelog'); | ||
try { | ||
const latestDate = await this.getLatestChangelogGeneratedDate(); // changes.md | ||
if (latestDate) { | ||
const changeLog = await this.getChangesAfterGivenDate(latestDate); // oai_changes.md | ||
if (changeLog) { | ||
this.logger.info('Updating the CHANGES.md'); | ||
const data = fs.readFileSync(this.cliCoreChangelogFilename); | ||
if (data.toString().includes(changeLog)) { | ||
this.logger.info(`Provided changes are already in cli core changeLog: ${changeLog}`); | ||
return; | ||
} | ||
const fd = fs.openSync(this.cliCoreChangelogFilename, 'w+'); | ||
const insert = Buffer.from(changeLog); | ||
fs.writeSync(fd, insert, 0, insert.length, 0); | ||
fs.writeSync(fd, data, 0, data.length, insert.length); | ||
fs.close(fd, (err) => { | ||
if (err) throw err; | ||
}); | ||
fs.writeFileSync('changeLog.md', changeLog); | ||
} | ||
} | ||
} catch (error) { | ||
this.logger.error(`Error while updating the changelog: ${error.message}`); | ||
throw new Error(error); | ||
} | ||
} | ||
|
||
async getReadLiner(filename) { | ||
if (!fs.existsSync(filename)) { | ||
throw new Error(`File not found: ${filename}`); | ||
} | ||
const fileStream = fs.createReadStream(filename); | ||
return readline.createInterface({ | ||
input: fileStream, | ||
}); | ||
} | ||
} | ||
module.exports = { | ||
ChangeLogHelper, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* eslint-disable no-console */ | ||
const { ChangeLogHelper } = require('./change-log-helper'); | ||
|
||
const ch = new ChangeLogHelper(); | ||
|
||
const getVersionType = async () => { | ||
const latestDate = await ch.getLatestChangelogGeneratedDate(); | ||
const versions = await ch.getAllReleaseVersionsFromGivenDate(latestDate); | ||
if (versions.length >= 2) { | ||
const version1 = versions[0].split('.'); | ||
const version2 = versions[versions.length - 1].split('.'); | ||
for (let i = 0; i < 3; i++) { | ||
if (version1[i] !== version2[i]) return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
(async () => { | ||
console.log(await getVersionType()); | ||
})(); | ||
module.exports = { | ||
getVersionType, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/bin/sh | ||
echo "Copying api-definitions" | ||
cp -R ~/oai_definitions/json/. src/services/twilio-api/ | ||
echo "Running update changelog script" | ||
node .github/scripts/update-change-log.js | ||
changeLog='' | ||
versionType=-1 | ||
if [ -f changeLog.md ]; then | ||
changeLog=$(cat changeLog.md) | ||
rm -rf changeLog.md | ||
if [ "$changeLog" != '' ]; then | ||
changeLog="${changeLog//'%'/'%25'}" | ||
changeLog="${changeLog//$'\n'/'%0A'}" | ||
changeLog="${changeLog//$'\r'/'%0D'}" | ||
versionType=$(node .github/scripts/get-version-type.js | tail -n -1) | ||
fi | ||
fi | ||
echo "Changelog: $changeLog" | ||
echo "Version type: $versionType" | ||
rm -rf OAI_CHANGES.md | ||
echo "Git configurations" | ||
git config --global user.email "[email protected]" | ||
git config --global user.name "twilio-dx" | ||
branch=$(git branch --show-current) | ||
echo "Current branch: $branch" | ||
git add -A | ||
if [ -n "$(git status --porcelain)" ]; then | ||
echo "There are changes to commit."; | ||
commitMessage='' | ||
if [ "$versionType" == 0 ] || [ "$versionType" == 1 ] | ||
then | ||
commitMessage='feat: Updated api definitions' | ||
elif [ "$versionType" == 2 ] | ||
then | ||
commitMessage='fix: Updated api definitions' | ||
else | ||
echo "Invalid versionType: $versionType"; | ||
exit | ||
fi | ||
echo "Commit message:$commitMessage" | ||
git commit -m "$commitMessage" | ||
git push origin "$branch" | ||
else | ||
echo "No changes to commit"; | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const { ChangeLogHelper } = require('./change-log-helper'); | ||
|
||
const ch = new ChangeLogHelper(); | ||
|
||
const updateChangeLog = async () => { | ||
return ch.appendChangesToChangelog(); | ||
}; | ||
(async () => { | ||
await updateChangeLog(); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,102 @@ | ||
|
||
name: Cli-core Release | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
cli-branch: | ||
description: 'Run cli workflow in the given branch' | ||
default: main | ||
homebrew-branch: | ||
description: 'HomeBrew branch name' | ||
default: main | ||
homebrew-prerelease: | ||
description: 'HomeBrew prerelease' | ||
default: 'false' | ||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [14.x] | ||
steps: | ||
- name: Checkout cli-core repo | ||
uses: actions/checkout@v2 | ||
- run: npm install | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: 'npm' | ||
- name: Run tests | ||
run: npm test | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [10.x,14.x] | ||
steps: | ||
- name: Checkout cli-core repo | ||
uses: actions/checkout@v2 | ||
- run: npm install | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: 'npm' | ||
- name: Run tests | ||
run: npm test | ||
update-api-specs: | ||
runs-on: ubuntu-latest | ||
needs: [test] | ||
outputs: | ||
change-log: ${{ steps.update-specs.outputs.change-log }} | ||
version-type: ${{ steps.update-specs.outputs.version-type }} | ||
steps: | ||
- name: Create temporary folder for copying json files from OAI repo | ||
run: mkdir -p ~/oai_definitions/json | ||
- name: Checkout OAI repo | ||
uses: actions/checkout@v2 | ||
with: | ||
repository: 'twilio/twilio-oai' | ||
token: ${{ secrets.REPO_ACCESS_TOKEN }} | ||
- run: | | ||
cp -R spec/json/. ~/oai_definitions/json/ | ||
cp -R CHANGES.md ~/oai_definitions/CHANGES.md | ||
- name: Checkout cli-core repo | ||
uses: actions/checkout@v2 | ||
- name: Update OAI specs | ||
id: update-specs | ||
run: | | ||
npm install | ||
cp -R ~/oai_definitions/CHANGES.md OAI_CHANGES.md | ||
source .github/scripts/update-api-spec-with-changelog.sh | ||
echo "::set-output name=change-log::$changeLog" | ||
echo "::set-output name=version-type::$versionType" | ||
release: | ||
runs-on: ubuntu-latest | ||
needs: [update-api-specs] | ||
outputs: | ||
tag-name: ${{ steps.semantic-release.outputs.TAG_NAME }} | ||
steps: | ||
- name: Checkout cli-core repo | ||
uses: actions/checkout@v2 | ||
- run: | | ||
git pull | ||
npm install | ||
- name: semanticRelease | ||
id: semantic-release | ||
run: npx semantic-release -t \${version} | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
update-release: | ||
runs-on: ubuntu-latest | ||
needs: [update-api-specs, release] | ||
steps: | ||
- name: Checkout cli-core repo | ||
uses: actions/checkout@v2 | ||
- name: Update release | ||
if: ${{needs.release.outputs.tag-name != ''}} | ||
uses: tubone24/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ github.token }} | ||
TAG_NAME: ${{needs.release.outputs.tag-name}} | ||
with: | ||
is_append_body: true | ||
body: ${{needs.update-api-specs.outputs.change-log}} | ||
triggerCliWorkflow: | ||
runs-on: ubuntu-latest | ||
needs: [ update-api-specs, update-release] | ||
steps: | ||
- name: Invoke CLI workflow with changelog and version-type | ||
if: ${{toJSON(needs.update-api-specs.outputs.change-log) != null && needs.update-api-specs.outputs.version-type != -1}} | ||
uses: benc-uk/workflow-dispatch@v1 | ||
with: | ||
workflow: Cli Release | ||
token: ${{ secrets.REPO_ACCESS_TOKEN }} | ||
repo: twilio/twilio-cli | ||
ref: ${{ github.event.inputs.cli-branch }} | ||
inputs: '{ "change-log": ${{ toJSON(needs.update-api-specs.outputs.change-log) }}, "version-type": "${{needs.update-api-specs.outputs.version-type}}", "home-brew-branch": "${{github.event.inputs.homebrew-branch}}", "pre-release": "${{github.event.inputs.homebrew-prerelease}}" }' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{ | ||
"branches": [ | ||
"main", | ||
{ | ||
"name": "release_feature_branch", | ||
"prerelease": "rc" | ||
} | ||
], | ||
"plugins": [ | ||
[ | ||
"@semantic-release/commit-analyzer", | ||
{ | ||
"preset": "angular", | ||
"releaseRules": [{ | ||
"type": "chore", | ||
"release": "patch" | ||
}] | ||
} | ||
], | ||
[ | ||
"@semantic-release/release-notes-generator", | ||
{ | ||
"preset": "conventionalcommits", | ||
"presetConfig": { | ||
"types": [{ | ||
"type": "feat", | ||
"section": "Library - Features" | ||
}, | ||
{ | ||
"type": "fix", | ||
"section": "Library - Fixes" | ||
}, | ||
{ | ||
"type": "chore", | ||
"section": "Library - Chores" | ||
}, | ||
{ | ||
"type": "test", | ||
"section": "Library - Test" | ||
}, | ||
{ | ||
"type": "docs", | ||
"section": "Library - Docs" | ||
} | ||
] | ||
} | ||
} | ||
], | ||
[ | ||
"@semantic-release/changelog", | ||
{ | ||
"changelogFile": "CHANGES.md" | ||
} | ||
], | ||
"@semantic-release/npm", | ||
"@semantic-release/github", | ||
[ | ||
"@semantic-release/git", | ||
{ | ||
"assets": [ | ||
"CHANGES.md", | ||
"package.json" | ||
], | ||
"message": "chore(release): set `package.json` to ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" | ||
} | ||
], | ||
[ | ||
"@semantic-release/exec", | ||
{ | ||
"successCmd": "echo '::set-output name=TAG_NAME::${nextRelease.version}'" | ||
} | ||
] | ||
] | ||
} |
Oops, something went wrong.