Merge pull request #81 from TriPSs/feature/pre-changelog-generation

fix: Fixes for pre changelog generation
releases/v3
Tycho Bokdam 2020-12-15 17:47:14 +01:00 committed by GitHub
commit 5cfbe896db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 527 additions and 162 deletions

View File

@ -1,8 +1,5 @@
name: 'Action to test the action locally with act' name: 'Test the action'
on: on: [ pull_request ]
push:
branches:
- branch-that-does-not-exist
jobs: jobs:
test-json: test-json:
@ -13,13 +10,31 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v1.5.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file.json'
- name: Show file
run: |
echo "$(<test-file.json)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file.json'
EXPECTED_VERSION: '1.5.0'
test-json-new: test-json-new:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -29,20 +44,32 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file-new.json' version-file: 'test-file-new.json'
- name: Show file - name: Show file
id: show
run: | run: |
echo "$(<test-file-new.json)" echo "$(<test-file-new.json)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file-new.json'
EXPECTED_VERSION: '0.1.0'
test-json-empty: test-json-empty:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -51,6 +78,12 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: touch ./test-file-empty.json - run: touch ./test-file-empty.json
- name: Generate changelog - name: Generate changelog
@ -58,56 +91,19 @@ jobs:
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: './test-file-empty.json' version-file: './test-file-empty.json'
- run: echo "$(<./test-file-empty.json)" - run: echo "$(<./test-file-empty.json)"
test-pre-commit: - name: Test output
runs-on: ubuntu-latest run: node ./test-output.js
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: "./"
- run: test -f pre-commit.test.json && (echo should not be here yet && exit 1) || exit 0
- name: Generate changelog
id: changelog
uses: ./
env: env:
ENV: 'dont-use-git' FILES: 'test-file-empty.json'
with: EXPECTED_VERSION: '0.1.0'
github-token: ${{ secrets.github_token }}
pre-commit: test/pre-commit.js
skip-on-empty: 'false'
- run: test -f pre-commit.test.json || (echo should be here && exit 1)
- run: cat pre-commit.test.json
test-pre-changelog-generation:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: "./"
- run: test -f pre-changelog-generation.test.json && (echo should not be here yet && exit 1) || exit 0
- name: Generate changelog
id: changelog
uses: ./
env:
ENV: 'dont-use-git'
with:
github-token: ${{ secrets.github_token }}
pre-changelog-generation: test/pre-changelog-generation.js
version-file: './test-file.toml'
- run: test -f pre-changelog-generation.test.json || (echo should be here && exit 1)
- run: cat pre-changelog-generation.test.json
test-git: test-git:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -116,11 +112,22 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: git tag | xargs git tag -d
- name: Create fake tag
run: "git tag -a 'v0.55.8' -m 'v0.55.8'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.56.0'
SKIPPED_COMMIT: true
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
skip-commit: 'true' skip-commit: 'true'
@ -132,7 +139,13 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: git tag | xargs git tag -d - run: git tag | xargs git tag -d
- name: Generate changelog - name: Generate changelog
@ -140,6 +153,8 @@ jobs:
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
SKIPPED_COMMIT: true
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
skip-commit: 'true' skip-commit: 'true'
@ -152,16 +167,34 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v9.5.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file.yaml' version-file: 'test-file.yaml'
version-path: 'package.version' version-path: 'package.version'
- name: Show file
run: |
echo "$(<test-file.yaml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file.yaml'
EXPECTED_VERSION: '9.5.0'
EXPECTED_VERSION_PATH: 'package.version'
test-yaml-new: test-yaml-new:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -170,6 +203,12 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: touch ./test-file-empty.yaml - run: touch ./test-file-empty.yaml
- name: Generate changelog - name: Generate changelog
@ -177,12 +216,22 @@ jobs:
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file-new.yaml' version-file: 'test-file-new.yaml'
version-path: 'package.version' version-path: 'package.version'
- run: echo "$(<test-file-new.yaml)" - name: Show file
run: |
echo "$(<test-file-new.yaml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file-new.yaml'
EXPECTED_VERSION: '0.1.0'
EXPECTED_VERSION_PATH: 'package.version'
test-yaml-empty: test-yaml-empty:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -192,17 +241,33 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: './test-file-empty.yaml' version-file: './test-file-empty.yaml'
version-path: 'package.version' version-path: 'package.version'
- run: echo "$(<./test-file-empty.yaml)" - name: Show file
run: |
echo "$(<test-file-empty.yaml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file-empty.yaml'
EXPECTED_VERSION: '0.1.0'
EXPECTED_VERSION_PATH: 'package.version'
test-toml: test-toml:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -212,16 +277,34 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.10.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file.toml' version-file: 'test-file.toml'
version-path: 'package.version' version-path: 'package.version'
- name: Show file
run: |
echo "$(<test-file.toml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file.toml'
EXPECTED_VERSION: '0.10.0'
EXPECTED_VERSION_PATH: 'package.version'
test-toml-new: test-toml-new:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -230,17 +313,33 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'test-file-new.toml' version-file: 'test-file-new.toml'
version-path: 'package.version' version-path: 'package.version'
- run: echo "$(<test-file-new.toml)" - name: Show file
run: |
echo "$(<test-file-new.toml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file-new.toml'
EXPECTED_VERSION: '0.1.0'
EXPECTED_VERSION_PATH: 'package.version'
test-toml-empty: test-toml-empty:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -250,6 +349,12 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: touch ./test-file-empty.toml - run: touch ./test-file-empty.toml
- name: Generate changelog - name: Generate changelog
@ -257,12 +362,89 @@ jobs:
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v6.5.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: './test/test-file-empty.toml' version-file: './test-file-empty.toml'
version-path: 'package.version'
fallback-version: '6.5.0'
- name: Show file
run: |
echo "$(<test-file-empty.toml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file-empty.toml'
EXPECTED_VERSION: '6.5.0'
EXPECTED_VERSION_PATH: 'package.version'
test-pre-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: test -f pre-commit.test.json && (echo should not be here yet && exit 1) || exit 0
- name: Generate changelog
id: changelog
uses: ./
env:
ENV: 'dont-use-git'
EXPECTED_TAG: 'v1.5.0'
with:
github-token: ${{ secrets.github_token }}
pre-commit: './test-pre-commit.js'
skip-on-empty: 'false'
version-file: './test-file.json'
- run: test -f pre-commit.test.json || (echo should be here && exit 1)
- run: cat pre-commit.test.json && echo ""
- run: cat ./package.json
test-pre-changelog-generation:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- run: test -f pre-changelog-generation.test.json && (echo should not be here yet && exit 1) || exit 0
- name: Generate changelog
id: changelog
uses: ./
env:
ENV: 'dont-use-git'
EXPECTED_TAG: 'v1.0.100-alpha'
with:
github-token: ${{ secrets.github_token }}
pre-changelog-generation: './test-pre-changelog-generation.js'
version-file: './test-file.toml'
version-path: 'package.version' version-path: 'package.version'
- run: echo "$(<./test/test-file-empty.toml)" - run: test -f pre-changelog-generation.version.test.json || (echo should be here && exit 1)
- run: test -f pre-changelog-generation.tag.test.json || (echo should be here && exit 1)
- run: cat pre-changelog-generation.version.test.json && echo ""
- run: cat pre-changelog-generation.tag.test.json && echo ""
- run: cat ./test-file.toml
test-multiple-files: test-multiple-files:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -272,14 +454,35 @@ jobs:
with: with:
path: "./" path: "./"
- run: npm ci --prod
- run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v1.5.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
version-file: 'package.json, package-lock.json' version-file: 'test-file.json, test-file.toml, test-file.yaml'
- name: Show files
run: |
echo "$(<test-file.json)"
echo ""
echo "$(<test-file.toml)"
echo ""
echo "$(<test-file.yaml)"
- name: Test output
run: node ./test-output.js
env:
FILES: 'test-file.json, test-file.toml, test-file.yaml'
EXPECTED_VERSION: '1.5.0, 0.1.0, 0.1.0'
test-config-file-path: test-config-file-path:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -289,15 +492,27 @@ jobs:
with: with:
path: "./" path: "./"
- name: Install Packages - run: npm ci --prod
run: yarn - run: touch ./fake-file.log
- run: "git config --global user.email 'changelog@github.com'"
- run: "git config --global user.name 'Awesome Github action'"
- run: "git add . && git commit -m 'feat: Added fake file so version will be bumped'"
- name: Generate Changelog - name: Generate Changelog
id: changelog id: changelog
uses: ./ uses: ./
env: env:
ENV: 'dont-use-git' ENV: 'dont-use-git'
EXPECTED_TAG: 'v0.1.0'
with: with:
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
skip-version-file: 'true' skip-version-file: 'true'
config-file-path: './test-changelog.config.js' config-file-path: './test-changelog.config.js'
- name: Test output
run: |
if grep -q "### New Features" "./CHANGELOG.md"; then
echo "Generated changelog file has config applied"
else
echo "Changelog config not applied" && exit 1
fi

View File

@ -58,17 +58,16 @@ A bunch of useful environment variables are available to the script with `proces
> Function in a specified file will be run right before the changelog generation phase, when the next > Function in a specified file will be run right before the changelog generation phase, when the next
> version is already known, but it was not used anywhere yet. It can be useful if you want to manually update version or tag. > version is already known, but it was not used anywhere yet. It can be useful if you want to manually update version or tag.
Same restrictions as for the pre-commit hook, but exported function name should be `preChangelogGeneration` Same restrictions as for the pre-commit hook, but exported functions names should be `preVersionGeneration` for modifications to the version and `preTagGeneration` for modifications to the git tag.
Following props will be passed to the function as a single parameter and same output is expected: Following props will be passed to the function as a single parameter and same output is expected:
```typescript ```typescript
interface Props { // Next version e.g. 1.12.3
tag: string; // Next tag e.g. v1.12.3 export function preVersionGeneration(version: string): string {}
version: string; // Next version e.g. 1.12.3
}
export function preChangelogGeneration(props: Props): Props {} // Next tag e.g. v1.12.3
export function preTagGeneration(tag: string): string {}
``` ```
### Config-File-Path ### Config-File-Path

View File

@ -86,7 +86,8 @@ inputs:
fallback-version: fallback-version:
description: 'The fallback version, if no older one can be detected, or if it is the first one' description: 'The fallback version, if no older one can be detected, or if it is the first one'
default: '0.1.0' default: '0.1.0'
required: false
config-file-path: config-file-path:
description: 'Path to the conventional changelog config file. If set, the preset setting will be ignored' description: 'Path to the conventional changelog config file. If set, the preset setting will be ignored'
required: false required: false

View File

@ -1,6 +1,8 @@
const core = require('@actions/core') const core = require('@actions/core')
const semverValid = require('semver').valid const semverValid = require('semver').valid
const requireScript = require('./requireScript')
/** /**
* Bumps the given version with the given release type * Bumps the given version with the given release type
* *
@ -8,7 +10,7 @@ const semverValid = require('semver').valid
* @param version * @param version
* @returns {string} * @returns {string}
*/ */
module.exports = (releaseType, version) => { module.exports = async (releaseType, version) => {
let major, minor, patch let major, minor, patch
if (version) { if (version) {
@ -44,5 +46,22 @@ module.exports = (releaseType, version) => {
core.info(`The version could not be detected, using fallback version '${major}.${minor}.${patch}'.`) core.info(`The version could not be detected, using fallback version '${major}.${minor}.${patch}'.`)
} }
return `${major}.${minor}.${patch}` const preChangelogGenerationFile = core.getInput('pre-changelog-generation')
let newVersion = `${major}.${minor}.${patch}`
if (preChangelogGenerationFile) {
const preChangelogGenerationScript = requireScript(preChangelogGenerationFile)
// Double check if we want to update / do something with the version
if (preChangelogGenerationScript && preChangelogGenerationScript.preVersionGeneration) {
const modifiedVersion = await preChangelogGenerationScript.preVersionGeneration(newVersion)
if (modifiedVersion) {
newVersion = modifiedVersion
}
}
}
return newVersion
} }

View File

@ -1,5 +1,6 @@
const core = require('@actions/core') const core = require('@actions/core')
const exec = require('@actions/exec') const exec = require('@actions/exec')
const assert = require('assert')
const { GITHUB_REPOSITORY, GITHUB_REF, ENV } = process.env const { GITHUB_REPOSITORY, GITHUB_REF, ENV } = process.env
@ -7,6 +8,8 @@ const branch = GITHUB_REF.replace('refs/heads/', '')
module.exports = new (class Git { module.exports = new (class Git {
commandsRun = []
constructor() { constructor() {
const githubToken = core.getInput('github-token', { required: true }) const githubToken = core.getInput('github-token', { required: true })
@ -16,10 +19,16 @@ module.exports = new (class Git {
const gitUserName = core.getInput('git-user-name') const gitUserName = core.getInput('git-user-name')
const gitUserEmail = core.getInput('git-user-email') const gitUserEmail = core.getInput('git-user-email')
// if the env is dont-use-git then we mock exec as we are testing a workflow locally // if the env is dont-use-git then we mock exec as we are testing a workflow
if (ENV === 'dont-use-git') { if (ENV === 'dont-use-git') {
this.exec = (command) => { this.exec = (command) => {
console.log(`Skipping "git ${command}" because of test env`) const fullCommand = `git ${command}`
console.log(`Skipping "${fullCommand}" because of test env`)
if (!fullCommand.includes('git remote set-url origin')) {
this.commandsRun.push(fullCommand)
}
} }
} }
@ -37,28 +46,14 @@ module.exports = new (class Git {
* @param command * @param command
* @return {Promise<>} * @return {Promise<>}
*/ */
exec = command => new Promise(async(resolve, reject) => { exec = (command) => new Promise(async(resolve, reject) => {
let myOutput = '' const exitCode = await exec.exec(`git ${command}`)
let myError = ''
const options = { if (exitCode === 0) {
listeners: { resolve()
stdout: (data) => {
myOutput += data.toString()
},
stderr: (data) => {
myError += data.toString()
},
},
}
try { } else {
await exec.exec(`git ${command}`, null, options) reject(`Command "git ${command}" exited with code ${exitCode}.`)
resolve(myOutput)
} catch (e) {
reject(e)
} }
}) })
@ -77,18 +72,17 @@ module.exports = new (class Git {
* @param file * @param file
* @returns {*} * @returns {*}
*/ */
add = file => this.exec(`add ${file}`) add = (file) => this.exec(`add ${file}`)
/** /**
* Commit all changes * Commit all changes
* *
* @param message * @param message
* @param args
* *
* @return {Promise<>} * @return {Promise<>}
*/ */
commit = (message, args = []) => ( commit = (message) => (
this.exec(`commit -m "${message}" ${args.join(' ')}`) this.exec(`commit -m "${message}"`)
) )
/** /**
@ -124,7 +118,7 @@ module.exports = new (class Git {
* *
* @return {Promise<>} * @return {Promise<>}
*/ */
isShallow = async () => { isShallow = async() => {
const isShallow = await this.exec('rev-parse --is-shallow-repository') const isShallow = await this.exec('rev-parse --is-shallow-repository')
// isShallow does not return anything on local machine // isShallow does not return anything on local machine
@ -141,7 +135,7 @@ module.exports = new (class Git {
* @param repo * @param repo
* @return {Promise<>} * @return {Promise<>}
*/ */
updateOrigin = repo => this.exec(`remote set-url origin ${repo}`) updateOrigin = (repo) => this.exec(`remote set-url origin ${repo}`)
/** /**
* Creates git tag * Creates git tag
@ -149,6 +143,35 @@ module.exports = new (class Git {
* @param tag * @param tag
* @return {Promise<>} * @return {Promise<>}
*/ */
createTag = tag => this.exec(`tag -a ${tag} -m "${tag}"`) createTag = (tag) => this.exec(`tag -a ${tag} -m "${tag}"`)
/**
* Validates the commands run
*/
testHistory = () => {
if (ENV === 'dont-use-git') {
const { EXPECTED_TAG, SKIPPED_COMMIT } = process.env
const expectedCommands = [
'git config user.name "Conventional Changelog Action"',
'git config user.email "conventional.changelog.action@github.com"',
'git rev-parse --is-shallow-repository',
'git pull --tags --ff-only',
]
if (!SKIPPED_COMMIT) {
expectedCommands.push('git add .')
expectedCommands.push(`git commit -m "chore(release): ${EXPECTED_TAG}"`)
}
expectedCommands.push(`git tag -a ${EXPECTED_TAG} -m "${EXPECTED_TAG}"`)
expectedCommands.push(`git push origin ${branch} --follow-tags`)
assert.deepStrictEqual(
this.commandsRun,
expectedCommands,
)
}
}
})() })()

View File

@ -0,0 +1,23 @@
const core = require('@actions/core')
const path = require('path')
const fs = require('fs')
/**
* Requires an script
*
* @param file
*/
module.exports = (file) => {
const fileLocation = path.resolve(process.cwd(), file)
// Double check the script exists before loading it
if (fs.existsSync(fileLocation)) {
core.info(`Loading "${fileLocation}" script`)
return require(fileLocation)
}
core.error(`Tried to load "${fileLocation}" script but it does not exists!`)
return undefined
}

View File

@ -5,6 +5,7 @@ const path = require('path')
const getVersioning = require('./version') const getVersioning = require('./version')
const git = require('./helpers/git') const git = require('./helpers/git')
const changelog = require('./helpers/generateChangelog') const changelog = require('./helpers/generateChangelog')
const requireScript = require('./helpers/requireScript')
async function handleVersioningByExtension(ext, file, versionPath, releaseType) { async function handleVersioningByExtension(ext, file, versionPath, releaseType) {
const versioning = getVersioning(ext) const versioning = getVersioning(ext)
@ -29,7 +30,7 @@ async function run() {
const gitUserEmail = core.getInput('git-user-email') const gitUserEmail = core.getInput('git-user-email')
const tagPrefix = core.getInput('tag-prefix') const tagPrefix = core.getInput('tag-prefix')
const preset = !core.getInput('config-file-path') ? core.getInput('preset') : '' const preset = !core.getInput('config-file-path') ? core.getInput('preset') : ''
const preCommit = core.getInput('pre-commit') const preCommitFile = core.getInput('pre-commit')
const outputFile = core.getInput('output-file') const outputFile = core.getInput('output-file')
const releaseCount = core.getInput('release-count') const releaseCount = core.getInput('release-count')
const versionFile = core.getInput('version-file') const versionFile = core.getInput('version-file')
@ -38,7 +39,7 @@ async function run() {
const skipCommit = core.getInput('skip-commit').toLowerCase() === 'true' const skipCommit = core.getInput('skip-commit').toLowerCase() === 'true'
const skipEmptyRelease = core.getInput('skip-on-empty').toLowerCase() === 'true' const skipEmptyRelease = core.getInput('skip-on-empty').toLowerCase() === 'true'
const conventionalConfigFile = core.getInput('config-file-path') const conventionalConfigFile = core.getInput('config-file-path')
const preChangelogGeneration = core.getInput('pre-changelog-generation') const preChangelogGenerationFile = core.getInput('pre-changelog-generation')
core.info(`Using "${preset}" preset`) core.info(`Using "${preset}" preset`)
core.info(`Using "${gitCommitMessage}" as commit message`) core.info(`Using "${gitCommitMessage}" as commit message`)
@ -51,12 +52,12 @@ async function run() {
core.info(`Using "${outputFile}" as output file`) core.info(`Using "${outputFile}" as output file`)
core.info(`Using "${conventionalConfigFile}" as config file`) core.info(`Using "${conventionalConfigFile}" as config file`)
if (preCommit) { if (preCommitFile) {
core.info(`Using "${preCommit}" as pre-commit script`) core.info(`Using "${preCommitFile}" as pre-commit script`)
} }
if (preChangelogGeneration) { if (preChangelogGenerationFile) {
core.info(`Using "${preChangelogGeneration}" as pre-changelog-generation script`) core.info(`Using "${preChangelogGenerationFile}" as pre-changelog-generation script`)
} }
core.info(`Skipping empty releases is "${skipEmptyRelease ? 'enabled' : 'disabled'}"`) core.info(`Skipping empty releases is "${skipEmptyRelease ? 'enabled' : 'disabled'}"`)
@ -65,9 +66,9 @@ async function run() {
core.info('Pull to make sure we have the full git history') core.info('Pull to make sure we have the full git history')
await git.pull() await git.pull()
const config = conventionalConfigFile && require(path.resolve(process.cwd(), conventionalConfigFile)) const config = conventionalConfigFile && requireScript(conventionalConfigFile)
conventionalRecommendedBump({ preset, tagPrefix, config }, async (error, recommendation) => { conventionalRecommendedBump({ preset, tagPrefix, config }, async(error, recommendation) => {
if (error) { if (error) {
core.setFailed(error.message) core.setFailed(error.message)
return return
@ -91,9 +92,11 @@ async function run() {
'git', 'git',
versionFile, versionFile,
versionPath, versionPath,
recommendation.releaseType recommendation.releaseType,
) )
newVersion = versioning.newVersion newVersion = versioning.newVersion
} else { } else {
const files = versionFile.split(',').map((f) => f.trim()) const files = versionFile.split(',').map((f) => f.trim())
core.info(`Files to bump: ${files.join(', ')}`) core.info(`Files to bump: ${files.join(', ')}`)
@ -102,8 +105,9 @@ async function run() {
files.map((file) => { files.map((file) => {
const fileExtension = file.split('.').pop() const fileExtension = file.split('.').pop()
core.info(`Bumping version to file "${file}" with extension "${fileExtension}"`) core.info(`Bumping version to file "${file}" with extension "${fileExtension}"`)
return handleVersioningByExtension(fileExtension, file, versionPath, recommendation.releaseType) return handleVersioningByExtension(fileExtension, file, versionPath, recommendation.releaseType)
}) }),
) )
newVersion = versioning[0].newVersion newVersion = versioning[0].newVersion
@ -111,15 +115,16 @@ async function run() {
let gitTag = `${tagPrefix}${newVersion}` let gitTag = `${tagPrefix}${newVersion}`
if (preChangelogGeneration) { if (preChangelogGenerationFile) {
const newVersionAndTag = await require(path.resolve(process.cwd(), preChangelogGeneration)).preChangelogGeneration({ const preChangelogGenerationScript = requireScript(preChangelogGenerationFile)
tag: gitTag,
version: newVersion,
})
if (newVersionAndTag) { // Double check if we want to update / do something with the tag
if (newVersionAndTag.tag) gitTag = newVersionAndTag.tag if (preChangelogGenerationScript && preChangelogGenerationScript.preTagGeneration) {
if (newVersionAndTag.version) newVersion = newVersionAndTag.version const modifiedTag = await preChangelogGenerationScript.preTagGeneration(gitTag)
if (modifiedTag) {
gitTag = modifiedTag
}
} }
} }
@ -147,12 +152,18 @@ async function run() {
if (!skipCommit) { if (!skipCommit) {
// Add changed files to git // Add changed files to git
if (preCommit) { if (preCommitFile) {
await require(path.resolve(process.cwd(), preCommit)).preCommit({ const preCommitScript = requireScript(preCommitFile)
tag: gitTag,
version: newVersion, // Double check if the file exists and the export exists
}) if (preCommitScript && preCommitScript.preCommit) {
await preCommitScript.preCommit({
tag: gitTag,
version: newVersion,
})
}
} }
await git.add('.') await git.add('.')
await git.commit(gitCommitMessage.replace('{version}', gitTag)) await git.commit(gitCommitMessage.replace('{version}', gitTag))
} }
@ -161,11 +172,7 @@ async function run() {
await git.createTag(gitTag) await git.createTag(gitTag)
core.info('Push all changes') core.info('Push all changes')
try { await git.push()
await git.push()
} catch (error) {
core.setFailed(error.message)
}
// Set outputs so other actions (for example actions/create-release) can use it // Set outputs so other actions (for example actions/create-release) can use it
core.setOutput('changelog', stringChangelog) core.setOutput('changelog', stringChangelog)
@ -173,9 +180,19 @@ async function run() {
core.setOutput('version', newVersion) core.setOutput('version', newVersion)
core.setOutput('tag', gitTag) core.setOutput('tag', gitTag)
core.setOutput('skipped', 'false') core.setOutput('skipped', 'false')
try {
// If we are running in test mode we use this to validate everything still runs
git.testHistory()
} catch (error) {
console.error(error)
core.setFailed(error)
}
}) })
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error)
} }
} }

View File

@ -12,11 +12,11 @@ module.exports = new (class Git extends BaseVersioning {
gitSemverTags({ gitSemverTags({
tagPrefix, tagPrefix,
}, (err, tags) => { }, async(err, tags) => {
const currentVersion = tags.length > 0 ? tags.shift().replace(tagPrefix, '') : null const currentVersion = tags.length > 0 ? tags.shift().replace(tagPrefix, '') : null
// Get the new version // Get the new version
this.newVersion = bumpVersion( this.newVersion = await bumpVersion(
releaseType, releaseType,
currentVersion, currentVersion,
) )

View File

@ -12,7 +12,7 @@ module.exports = new (class Json extends BaseVersioning {
* @param {!string} releaseType - The type of release * @param {!string} releaseType - The type of release
* @return {*} * @return {*}
*/ */
bump = (releaseType) => { bump = async(releaseType) => {
// Read the file // Read the file
const fileContent = this.read() const fileContent = this.read()
@ -33,7 +33,7 @@ module.exports = new (class Json extends BaseVersioning {
const oldVersion = objectPath.get(jsonContent, this.versionPath, null) const oldVersion = objectPath.get(jsonContent, this.versionPath, null)
// Get the new version // Get the new version
this.newVersion = bumpVersion( this.newVersion = await bumpVersion(
releaseType, releaseType,
oldVersion, oldVersion,
) )

View File

@ -4,7 +4,7 @@ const toml = require('@iarna/toml')
const BaseVersioning = require('./base') const BaseVersioning = require('./base')
const bumpVersion = require('../helpers/bumpVersion') const bumpVersion = require('../helpers/bumpVersion')
module.exports = new (class Toml extends BaseVersioning{ module.exports = new (class Toml extends BaseVersioning {
/** /**
* Bumps the version in the package.json * Bumps the version in the package.json
@ -12,14 +12,14 @@ module.exports = new (class Toml extends BaseVersioning{
* @param {!string} releaseType - The type of release * @param {!string} releaseType - The type of release
* @return {*} * @return {*}
*/ */
bump = (releaseType) => { bump = async(releaseType) => {
// Read the file // Read the file
const fileContent = this.read() const fileContent = this.read()
const tomlContent = toml.parse(fileContent) const tomlContent = toml.parse(fileContent)
const oldVersion = objectPath.get(tomlContent, this.versionPath, null) const oldVersion = objectPath.get(tomlContent, this.versionPath, null)
// Get the new version // Get the new version
this.newVersion = bumpVersion( this.newVersion = await bumpVersion(
releaseType, releaseType,
oldVersion, oldVersion,
) )

View File

@ -4,7 +4,7 @@ const yaml = require('yaml')
const BaseVersioning = require('./base') const BaseVersioning = require('./base')
const bumpVersion = require('../helpers/bumpVersion') const bumpVersion = require('../helpers/bumpVersion')
module.exports = new (class Yaml extends BaseVersioning{ module.exports = new (class Yaml extends BaseVersioning {
/** /**
* Bumps the version in the package.json * Bumps the version in the package.json
@ -12,14 +12,14 @@ module.exports = new (class Yaml extends BaseVersioning{
* @param {!string} releaseType - The type of release * @param {!string} releaseType - The type of release
* @return {*} * @return {*}
*/ */
bump = (releaseType) => { bump = async(releaseType) => {
// Read the file // Read the file
const fileContent = this.read() const fileContent = this.read()
const yamlContent = yaml.parse(fileContent) || {} const yamlContent = yaml.parse(fileContent) || {}
const oldVersion = objectPath.get(yamlContent, this.versionPath, null) const oldVersion = objectPath.get(yamlContent, this.versionPath, null)
// Get the new version // Get the new version
this.newVersion = bumpVersion( this.newVersion = await bumpVersion(
releaseType, releaseType,
oldVersion, oldVersion,
) )

4
test-file.json 100644
View File

@ -0,0 +1,4 @@
{
"name": "Test JSON",
"version": "1.4.5"
}

View File

@ -3,4 +3,4 @@ title = "test"
# Comment # Comment
[package] [package]
name = "test file" name = "test file"
version = "0.1.0" version = "0.9.3"

View File

@ -1,5 +1,5 @@
package: package:
version: '0.1.0' version: '9.4.5'
# Comment # Comment
different: different:

57
test-output.js 100644
View File

@ -0,0 +1,57 @@
const fs = require('fs')
const assert = require('assert')
const objectPath = require('object-path')
const yaml = require('yaml')
const toml = require('@iarna/toml')
const actionConfig = yaml.parse(fs.readFileSync('./action.yml', 'utf8'))
const {
FILES = actionConfig.inputs['version-file'].default,
EXPECTED_VERSION_PATH = actionConfig.inputs['version-path'].default,
EXPECTED_VERSION = actionConfig.inputs['fallback-version'].default,
} = process.env
assert.ok(FILES, 'Files not defined!')
/**
* Test if all the files are updated
*/
FILES.split(',').map((file, index) => {
const fileContent = fs.readFileSync(file.trim(), 'utf8')
const fileExtension = file.split('.').pop()
assert.ok(fileExtension, 'No file extension found!')
let parsedContent = null
switch (fileExtension.toLowerCase()) {
case 'json':
parsedContent = JSON.parse(fileContent)
break
case 'yaml':
case 'yml':
parsedContent = yaml.parse(fileContent)
break
case 'toml':
parsedContent = toml.parse(fileContent)
break
default:
assert.fail('File extension not supported!')
}
assert.ok(parsedContent, 'Content could not be parsed!')
const newVersionInFile = objectPath.get(parsedContent, EXPECTED_VERSION_PATH, null)
const expectedVersions = EXPECTED_VERSION.split(',')
const expectedVersion = expectedVersions.length > 0
? expectedVersions[index]
: expectedVersions
assert.strictEqual(newVersionInFile, expectedVersion.trim(), 'Version does not match what is expected')
})

View File

@ -0,0 +1,29 @@
const fs = require('fs')
const assert = require('assert')
exports.preVersionGeneration = (version) => {
const { GITHUB_WORKSPACE } = process.env
assert.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty')
assert.ok(version, 'version should not be empty')
const newVersion = '1.0.100'
fs.writeFileSync('pre-changelog-generation.version.test.json', newVersion)
return newVersion
}
exports.preTagGeneration = (tag) => {
const { GITHUB_WORKSPACE } = process.env
assert.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty')
assert.ok(tag, 'tag should not be empty')
assert.strictEqual(tag, 'v1.0.100')
const newTag = 'v1.0.100-alpha'
fs.writeFileSync('pre-changelog-generation.tag.test.json', newTag)
return newTag
}

View File

@ -1,12 +1,12 @@
const fs = require('fs') const fs = require('fs')
const t = require('assert') const assert = require('assert')
exports.preCommit = (props) => { exports.preCommit = (props) => {
const {GITHUB_WORKSPACE} = process.env; const {GITHUB_WORKSPACE} = process.env;
t.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty') assert.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty')
t.ok(props.tag, 'tag should not be empty') assert.ok(props.tag, 'tag should not be empty')
t.ok(props.version, 'version should not be empty') assert.ok(props.version, 'version should not be empty')
const body = { const body = {
workspace: GITHUB_WORKSPACE, workspace: GITHUB_WORKSPACE,

View File

@ -1,22 +0,0 @@
const fs = require('fs')
const t = require('assert')
exports.preChangelogGeneration = (props) => {
const { GITHUB_WORKSPACE } = process.env
t.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty')
t.ok(props.tag, 'tag should not be empty')
t.ok(props.version, 'version should not be empty')
const newVersion = '1.0.100'
const newTag = 'v1.0.100'
const body = {
version: newVersion,
tag: newTag,
}
fs.writeFileSync('pre-changelog-generation.test.json', JSON.stringify(body, null, 2))
return body
}