Skip to content

Commit

Permalink
feat: added script to generate changelog automatically for releases
Browse files Browse the repository at this point in the history
  • Loading branch information
flawiddsouza committed Apr 7, 2023
1 parent 7e55533 commit bf00d63
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,17 @@ jobs:
- name: Publish docker image
run: |
docker push flawiddsouza/restfox:${{ env.VERSION }}
update-release-notes:
needs: [build-electron-linux, build-electron-windows, build-electron-mac, build-docker-image]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history
- name: Setup Node 16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Generate & Update Release Notes
run: |
node scripts/update-release-notes.js
53 changes: 53 additions & 0 deletions scripts/generate-changelog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const { execSync } = require('child_process')

// Get the last two tags
const tags = execSync('git tag --sort=committerdate').toString().trim().split('\n').reverse().slice(0, 2)
const fromTag = tags[1]
const toTag = tags[0]

// Get the commit messages between the two tags
const commitMessages = execSync(
`git log --pretty=format:'%s' ${fromTag}..${toTag}`
).toString()

// Split the commit messages into an array
const commits = commitMessages.trim().split('\n').reverse()

// Initialize empty arrays to store the different types of changes
let newFeatures = []
let fixes = []

// Loop through each commit message and categorize it based on the conventional commits spec
commits.forEach((commit) => {
if (commit.startsWith('feat') || commit.startsWith('feat(ui)')) {
newFeatures.push(commit.slice(commit.indexOf(':') + 1).trim())
} else if (commit.startsWith('fix') || commit.startsWith('fix(ui)')) {
fixes.push(commit.slice(commit.indexOf(':') + 1).trim())
}
})

// Print the changelog in the desired format
console.log("### What's New")
if (newFeatures.length > 0) {
console.log('- ' + newFeatures.join('\n- '))
}
if (fixes.length > 0) {
console.log('\n### Fixes')
console.log('- ' + fixes.join('\n- '))
}
console.log(`
### Packages
For **Ubuntu**, snap can be installed using:
\`\`\`
sudo snap install restfox
\`\`\`
For **MacOS**, the app can be installed using homebrew:
\`\`\`
brew install restfox
\`\`\`
**NOTE:** Not all the builds have been tested properly, so please create an issue if you encounter any problems.
`)
console.log(`\n**Full Changelog**: https://github.com/flawiddsouza/Restfox/compare/${fromTag}...${toTag}`)
105 changes: 105 additions & 0 deletions scripts/update-release-notes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const { execSync } = require('child_process')
const https = require('https')

const GITHUB_TOKEN = process.env.GITHUB_TOKEN
const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY
const GITHUB_REF = process.env.GITHUB_REF

const generateReleaseNotes = () => {
const output = execSync('node scripts/generate-changelog.js', { encoding: 'utf8' })
return output
}

const getVersionFromTag = () => {
return GITHUB_REF.replace('refs/tags/', '')
}

const makeRequest = (options, payload = null) => {
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = ''

res.on('data', (chunk) => {
data += chunk
})

res.on('end', () => {
resolve({
statusCode: res.statusCode,
headers: res.headers,
data: JSON.parse(data),
})
})
})

req.on('error', (error) => {
reject(error)
})

if (payload) {
req.write(payload)
}

req.end()
})
}

const updateReleaseNotes = async (version, releaseNotes) => {
const getRequestOptions = {
hostname: 'api.github.com',
path: `/repos/${GITHUB_REPOSITORY}/releases`,
method: 'GET',
headers: {
Authorization: `token ${GITHUB_TOKEN}`,
Accept: 'application/vnd.github+json',
'User-Agent': 'Node.js',
},
}

const response = await makeRequest(getRequestOptions)

const releaseData = response.data.find((release) => release.tag_name === version)

if (!releaseData) {
console.error(`Release not found for tag ${version}`)
process.exit(1)
}

const releaseId = releaseData.id
const releaseNotesJson = JSON.stringify({
body: releaseNotes,
tag_name: version,
prerelease: false,
})

const patchOptions = {
...getRequestOptions,
path: `/repos/${GITHUB_REPOSITORY}/releases/${releaseId}`,
method: 'PATCH',
headers: {
...getRequestOptions.headers,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(releaseNotesJson),
},
}

const patchResponse = await makeRequest(patchOptions, releaseNotesJson)

if (patchResponse.statusCode !== 200) {
console.error('Failed to update release notes')
console.log(patchResponse.data)
process.exit(1)
} else {
console.log('Release notes updated successfully')
process.exit()
}
}

const main = async () => {
const releaseNotes = generateReleaseNotes()
const version = getVersionFromTag()

await updateReleaseNotes(version, releaseNotes)
}

main()

0 comments on commit bf00d63

Please sign in to comment.