commit
a860a263fa
|
@ -1,18 +1,15 @@
|
||||||
|
name: 'release'
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- 'releases/*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
hello_world_job:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: A job to say hello
|
|
||||||
steps:
|
steps:
|
||||||
- name: Hello world action step
|
- uses: actions/checkout@v1
|
||||||
id: hello
|
|
||||||
uses: actions/hello-world-javascript-action@v1
|
- uses: ./
|
||||||
with:
|
with:
|
||||||
who-to-greet: 'Mona the Octocat'
|
github-token: ${{ secrets.github_token }}
|
||||||
# Use the output from the `hello` step
|
|
||||||
- name: Get the output time
|
|
||||||
run: echo "The time was ${{ steps.hello.outputs.time }}"
|
|
||||||
|
|
|
@ -1 +1,66 @@
|
||||||
node_modules
|
# comment this out distribution branches
|
||||||
|
# node_modules/
|
||||||
|
|
||||||
|
# Editors
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Other Dependency directories
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
33
README.md
33
README.md
|
@ -1,21 +1,36 @@
|
||||||
# Conventional Changelog action
|
# Conventional Changelog action
|
||||||
|
|
||||||
This action will generate a conventional changelog, tag the commit and push all the changes.
|
This action will bump version, tag commit and generate a changelog with conventional commits.
|
||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
|
|
||||||
### `who-to-greet`
|
### `github-token`
|
||||||
|
|
||||||
**Required** The name of the person to greet. Default `"World"`.
|
**Required** Github token.
|
||||||
|
|
||||||
## Outputs
|
### `git-message`
|
||||||
|
|
||||||
### `time`
|
**Optional** Commit message that is used when committing the changelog.
|
||||||
|
|
||||||
The time we greeted you.
|
### `preset`
|
||||||
|
|
||||||
|
**Optional** Preset that is used from conventional commits. Default `angular`.
|
||||||
|
|
||||||
|
### `tag-prefix`
|
||||||
|
|
||||||
|
**Optional** Prefix for the git tags. Default `v`.
|
||||||
|
|
||||||
|
### `output-file`
|
||||||
|
|
||||||
|
**Optional** File to output the changelog to. Default `CHANGELOG.md`.
|
||||||
|
|
||||||
## Example usage
|
## Example usage
|
||||||
|
|
||||||
uses: actions/hello-world-javascript-action@v1
|
- name: Conventional Changelog Action
|
||||||
with:
|
uses: TriPSs/conventional-changelog-action@v0.0.1
|
||||||
git-: 'Mona the Octocat'
|
with:
|
||||||
|
github-token: ${{ secrets.github_token }}
|
||||||
|
git-message: 'chore(release): {version}'
|
||||||
|
preset: 'angular'
|
||||||
|
tag-prefix: 'v'
|
||||||
|
output-file: 'CHANGELOG.md'
|
||||||
|
|
24
action.yml
24
action.yml
|
@ -4,9 +4,31 @@ author: 'Tycho Bokdam'
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'src/index.js'
|
main: 'src/index.js'
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
icon: 'edit'
|
icon: 'edit'
|
||||||
color: 'red'
|
color: 'red'
|
||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
- git-message: 'chore: Release {version}'
|
github-token:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
git-message:
|
||||||
|
description: 'Commit message to use'
|
||||||
|
default: 'chore(release): {version}'
|
||||||
|
required: false
|
||||||
|
|
||||||
|
preset:
|
||||||
|
description: 'The preset from Conventional Changelog to use'
|
||||||
|
default: 'angular'
|
||||||
|
required: false
|
||||||
|
|
||||||
|
tag-prefix:
|
||||||
|
description: 'Prefix that is used for the git tag'
|
||||||
|
default: 'v'
|
||||||
|
required: false
|
||||||
|
|
||||||
|
output-file:
|
||||||
|
description: 'File to output the changelog to'
|
||||||
|
default: 'CHANGELOG.md'
|
||||||
required: false
|
required: false
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "conventional-changelog-action",
|
"name": "conventional-changelog-action",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -19,6 +19,8 @@
|
||||||
"homepage": "https://github.com/TriPSs/conventional-changelog-action#readme",
|
"homepage": "https://github.com/TriPSs/conventional-changelog-action#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.1.3",
|
"@actions/core": "^1.1.3",
|
||||||
"@actions/github": "^1.1.0"
|
"@actions/exec": "^1.0.1",
|
||||||
|
"conventional-changelog": "^3.1.12",
|
||||||
|
"conventional-recommended-bump": "^6.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
const conventionalChangelog = require('conventional-changelog')
|
||||||
|
|
||||||
|
module.exports = (tagPrefix, preset, jsonPackage, fileName) => new Promise((resolve) => {
|
||||||
|
const changelogStream = conventionalChangelog({
|
||||||
|
preset,
|
||||||
|
releaseCount: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: jsonPackage.version,
|
||||||
|
currentTag: `${tagPrefix}${jsonPackage.version}`,
|
||||||
|
tagPrefix,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
changelogStream
|
||||||
|
.pipe(fs.createWriteStream(fileName))
|
||||||
|
.on('finish', resolve)
|
||||||
|
})
|
|
@ -0,0 +1,121 @@
|
||||||
|
const core = require('@actions/core')
|
||||||
|
const exec = require('@actions/exec')
|
||||||
|
|
||||||
|
const { GITHUB_REPOSITORY, GITHUB_REF } = process.env
|
||||||
|
|
||||||
|
const branch = GITHUB_REF.replace('refs/heads/', '')
|
||||||
|
|
||||||
|
module.exports = new (class Git {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const githubToken = core.getInput('github-token', { required: true })
|
||||||
|
|
||||||
|
// Make the Github token secret
|
||||||
|
core.setSecret(githubToken)
|
||||||
|
|
||||||
|
// Set config
|
||||||
|
this.config('user.name', 'Conventional Changelog Action')
|
||||||
|
this.config('user.email', 'conventional.changelog.action@github.com')
|
||||||
|
|
||||||
|
// Update the origin
|
||||||
|
this.updateOrigin(`https://x-access-token:${githubToken}@github.com/${GITHUB_REPOSITORY}.git`)
|
||||||
|
|
||||||
|
// Checkout the branch
|
||||||
|
this.checkout()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the git command
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
exec = command => new Promise(async(resolve, reject) => {
|
||||||
|
let myOutput = ''
|
||||||
|
let myError = ''
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
listeners: {
|
||||||
|
stdout: (data) => {
|
||||||
|
myOutput += data.toString()
|
||||||
|
},
|
||||||
|
stderr: (data) => {
|
||||||
|
myError += data.toString()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await exec.exec(`git ${command}`, null, options)
|
||||||
|
|
||||||
|
resolve(myOutput)
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a git config prop
|
||||||
|
*
|
||||||
|
* @param prop
|
||||||
|
* @param value
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
config = (prop, value) => this.exec(`config ${prop} "${value}"`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a file to commit
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
add = file => this.exec(`add ${file}`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit all changes
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param args
|
||||||
|
*
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
commit = (message, args = []) => (
|
||||||
|
this.exec(`commit -m "${message}" ${args.join(' ')}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push all changes
|
||||||
|
*
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
push = () => (
|
||||||
|
this.exec(`push origin ${branch} --follow-tags`)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checkout branch
|
||||||
|
*
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
checkout = () => (
|
||||||
|
this.exec(`checkout ${branch}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the origin remote
|
||||||
|
*
|
||||||
|
* @param repo
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
updateOrigin = repo => this.exec(`remote set-url origin ${repo}`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates git tag
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @return {Promise<>}
|
||||||
|
*/
|
||||||
|
createTag = tag => this.exec(`tag -a ${tag} -m "${tag}"`)
|
||||||
|
|
||||||
|
})()
|
|
@ -0,0 +1,58 @@
|
||||||
|
const path = require('path')
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const packageJsonLoc = path.resolve('./', 'package.json')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get's the project package.json
|
||||||
|
* @return {any}
|
||||||
|
*/
|
||||||
|
get: () => {
|
||||||
|
return JSON.parse(fs.readFileSync(packageJsonLoc))
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bumps the version in the package.json
|
||||||
|
*
|
||||||
|
* @param packageJson
|
||||||
|
* @param releaseType
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
bump: (packageJson, releaseType) => {
|
||||||
|
let [major, minor, patch] = packageJson.version.split('.')
|
||||||
|
|
||||||
|
switch (releaseType) {
|
||||||
|
case 'major':
|
||||||
|
major = parseInt(major, 10) + 1
|
||||||
|
minor = 0
|
||||||
|
patch = 0
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'minor':
|
||||||
|
minor = parseInt(minor, 10) + 1
|
||||||
|
patch = 0
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
patch = parseInt(patch, 10) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the package.json with the new version
|
||||||
|
packageJson.version = `${major}.${minor}.${patch}`
|
||||||
|
|
||||||
|
return packageJson
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update package.json
|
||||||
|
*
|
||||||
|
* @param packageJson
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
update: (packageJson) => (
|
||||||
|
fs.writeFileSync(packageJsonLoc, JSON.stringify(packageJson, null, 2))
|
||||||
|
),
|
||||||
|
|
||||||
|
}
|
59
src/index.js
59
src/index.js
|
@ -1,18 +1,53 @@
|
||||||
const core = require('@actions/core')
|
const core = require('@actions/core')
|
||||||
const github = require('@actions/github')
|
const conventionalRecommendedBump = require('conventional-recommended-bump')
|
||||||
|
|
||||||
try {
|
const git = require('./helpers/git')
|
||||||
// `who-to-greet` input defined in action metadata file
|
const packageJson = require('./helpers/packageJson')
|
||||||
const nameToGreet = core.getInput('who-to-greet')
|
const generateChangelog = require('./helpers/generateChangelog')
|
||||||
console.log(`Hello ${nameToGreet}!`)
|
|
||||||
|
|
||||||
const time = (new Date()).toTimeString()
|
async function run() {
|
||||||
core.setOutput('time', time)
|
try {
|
||||||
|
const commitMessage = core.getInput('git-message')
|
||||||
|
const tagPrefix = core.getInput('tag-prefix')
|
||||||
|
const preset = core.getInput('preset')
|
||||||
|
const outputFile = core.getInput('output-file')
|
||||||
|
|
||||||
// Get the JSON webhook payload for the event that triggered the workflow
|
core.info(`Using "${preset}" preset`)
|
||||||
const payload = JSON.stringify(github.context.payload, undefined, 2)
|
|
||||||
console.log(`The event payload: ${payload}`)
|
|
||||||
|
|
||||||
} catch (error) {
|
conventionalRecommendedBump({ preset }, async(error, recommendation) => {
|
||||||
core.setFailed(error.message)
|
if (error) {
|
||||||
|
core.setFailed(error.message)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
core.info(`Recommended release type: ${recommendation.releaseType}`)
|
||||||
|
|
||||||
|
// Bump the version in the package.json
|
||||||
|
const jsonPackage = packageJson.bump(
|
||||||
|
packageJson.get(),
|
||||||
|
recommendation.releaseType,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update the package.json file
|
||||||
|
packageJson.update(jsonPackage)
|
||||||
|
|
||||||
|
core.info(`New version: ${jsonPackage.version}`)
|
||||||
|
|
||||||
|
// Generate the changelog
|
||||||
|
await generateChangelog(tagPrefix, preset, jsonPackage, outputFile)
|
||||||
|
|
||||||
|
core.info('Push all changes')
|
||||||
|
|
||||||
|
// Add changed files to git
|
||||||
|
await git.add('.')
|
||||||
|
await git.commit(commitMessage.replace('{version}', `${tagPrefix}${jsonPackage.version}`))
|
||||||
|
await git.createTag(`${tagPrefix}${jsonPackage.version}`)
|
||||||
|
await git.push()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
|
|
Loading…
Reference in New Issue