Fixes #135 Add support for generate_release_notes
Some checks failed
Test / check_pr (push) Has been cancelled

This commit is contained in:
Nick Cipollo
2021-11-26 16:11:52 -05:00
parent 66aaa1eb00
commit 40bb172bd0
15 changed files with 134 additions and 23 deletions

View File

@@ -13,6 +13,7 @@ This action will create a GitHub release and optionally upload an artifact to it
- **commit**: An optional commit reference. This will be used to create the tag if it does not exist. - **commit**: An optional commit reference. This will be used to create the tag if it does not exist.
- **discussionCategory**: When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases. - **discussionCategory**: When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases.
- **draft**: Optionally marks this release as a draft release. Set to `true` to enable. - **draft**: Optionally marks this release as a draft release. Set to `true` to enable.
- **generateReleaseNotes**: Indicates if release notes should be automatically generated. Set to `true` to enable.
- **name**: An optional name for the release. If this is omitted the tag will be used. - **name**: An optional name for the release. If this is omitted the tag will be used.
- **omitBody**: Indicates if the release body should be omitted. - **omitBody**: Indicates if the release body should be omitted.
- **omitBodyDuringUpdate**: Indicates if the release body should be omitted during updates. The body will still be applied for newly created releases. This will preserve the existing body during updates. - **omitBodyDuringUpdate**: Indicates if the release body should be omitted during updates. The body will still be applied for newly created releases. This will preserve the existing body during updates.

View File

@@ -26,6 +26,7 @@ const createName = 'createName'
const commit = 'commit' const commit = 'commit'
const discussionCategory = 'discussionCategory' const discussionCategory = 'discussionCategory'
const draft = true const draft = true
const generateReleaseNotes = true
const id = 100 const id = 100
const createPrerelease = true const createPrerelease = true
const updatePrerelease = false const updatePrerelease = false
@@ -51,7 +52,14 @@ describe("Action", () => {
await action.perform() await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease)
expect(uploadMock).not.toBeCalled() expect(uploadMock).not.toBeCalled()
assertOutputApplied() assertOutputApplied()
}) })
@@ -63,7 +71,15 @@ describe("Action", () => {
await action.perform() await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url) expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied() assertOutputApplied()
}) })
@@ -80,7 +96,16 @@ describe("Action", () => {
await action.perform() await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url) expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied() assertOutputApplied()
@@ -91,7 +116,16 @@ describe("Action", () => {
await action.perform() await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url) expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied() assertOutputApplied()
}) })
@@ -125,7 +159,16 @@ describe("Action", () => {
expect(error).toEqual("error") expect(error).toEqual("error")
} }
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).not.toBeCalled() expect(uploadMock).not.toBeCalled()
}) })
@@ -191,7 +234,16 @@ describe("Action", () => {
expect(error).toEqual(expectedError) expect(error).toEqual(expectedError)
} }
expect(createMock).toBeCalledWith(tag, createBody, commit, discussionCategory, draft, createName, createPrerelease) expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
draft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url) expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
}) })
@@ -315,6 +367,7 @@ describe("Action", () => {
commit: commit, commit: commit,
discussionCategory: discussionCategory, discussionCategory: discussionCategory,
draft: draft, draft: draft,
generateReleaseNotes: true,
owner: "owner", owner: "owner",
createdPrerelease: createPrerelease, createdPrerelease: createPrerelease,
replacesArtifacts: replacesArtifacts, replacesArtifacts: replacesArtifacts,

View File

@@ -38,9 +38,16 @@ describe('Inputs', () => {
inputs = new CoreInputs(createGlobber(), context) inputs = new CoreInputs(createGlobber(), context)
}) })
it('returns targetCommit', () => { describe('commit', () => {
mockGetInput.mockReturnValue('42') it('returns commit', () => {
expect(inputs.commit).toBe('42') mockGetInput.mockReturnValueOnce('commit')
expect(inputs.commit).toBe('commit')
})
it('returns undefined when omitted', () => {
mockGetInput.mockReturnValueOnce('')
expect(inputs.commit).toBeUndefined()
})
}) })
it('returns token', () => { it('returns token', () => {
@@ -202,6 +209,18 @@ describe('Inputs', () => {
}) })
}) })
describe('generateReleaseNotes', () => {
it('returns returns true', function () {
mockGetInput.mockReturnValue("true")
expect(inputs.generateReleaseNotes).toBe(true)
});
it('returns false when omitted', function () {
mockGetInput.mockReturnValue("")
expect(inputs.generateReleaseNotes).toBe(false)
});
})
describe('owner', () => { describe('owner', () => {
it('returns owner from context', function () { it('returns owner from context', function () {
process.env.GITHUB_REPOSITORY = "owner/repo" process.env.GITHUB_REPOSITORY = "owner/repo"

View File

@@ -43,9 +43,10 @@ describe.skip('Integration Test', () => {
artifacts: artifacts(), artifacts: artifacts(),
createdReleaseBody: "This release was generated by release-action's integration test", createdReleaseBody: "This release was generated by release-action's integration test",
createdReleaseName: "Releases Action Integration Test", createdReleaseName: "Releases Action Integration Test",
commit: "", commit: undefined,
discussionCategory: 'Release', discussionCategory: 'Release',
draft: false, draft: false,
generateReleaseNotes: true,
owner: "ncipollo", owner: "ncipollo",
createdPrerelease: false, createdPrerelease: false,
replacesArtifacts: true, replacesArtifacts: true,

View File

@@ -43,6 +43,10 @@ inputs:
description: "Optionally marks this release as a draft release. Set to true to enable." description: "Optionally marks this release as a draft release. Set to true to enable."
required: false required: false
default: '' default: ''
generateReleaseNotes:
description: 'Indicates if release notes should be automatically generated.'
required: false
default: 'false'
name: name:
description: 'An optional name for the release. If this is omitted the tag will be used.' description: 'An optional name for the release. If this is omitted the tag will be used.'
required: false required: false

15
dist/index.js vendored
View File

@@ -100,7 +100,7 @@ class Action {
} }
createRelease() { createRelease() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.createdPrerelease); return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.generateReleaseNotes, this.inputs.createdReleaseName, this.inputs.createdPrerelease);
}); });
} }
} }
@@ -640,7 +640,11 @@ class CoreInputs {
return ''; return '';
} }
get commit() { get commit() {
return core.getInput('commit'); const commit = core.getInput('commit');
if (commit) {
return commit;
}
return undefined;
} }
get createdReleaseName() { get createdReleaseName() {
if (CoreInputs.omitName) if (CoreInputs.omitName)
@@ -668,6 +672,10 @@ class CoreInputs {
const draft = core.getInput('draft'); const draft = core.getInput('draft');
return draft == 'true'; return draft == 'true';
} }
get generateReleaseNotes() {
const generate = core.getInput('generateReleaseNotes');
return generate == 'true';
}
get owner() { get owner() {
let owner = core.getInput('owner'); let owner = core.getInput('owner');
if (owner) { if (owner) {
@@ -802,7 +810,7 @@ class GithubReleases {
this.inputs = inputs; this.inputs = inputs;
this.git = git; this.git = git;
} }
create(tag, body, commitHash, discussionCategory, draft, name, prerelease) { create(tag, body, commitHash, discussionCategory, draft, generateReleaseNotes, name, prerelease) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// noinspection TypeScriptValidateJSTypes // noinspection TypeScriptValidateJSTypes
return this.git.rest.repos.createRelease({ return this.git.rest.repos.createRelease({
@@ -810,6 +818,7 @@ class GithubReleases {
name: name, name: name,
discussion_category_name: discussionCategory, discussion_category_name: discussionCategory,
draft: draft, draft: draft,
generate_release_notes: generateReleaseNotes,
owner: this.inputs.owner, owner: this.inputs.owner,
prerelease: prerelease, prerelease: prerelease,
repo: this.inputs.repo, repo: this.inputs.repo,

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -93,7 +93,7 @@ class Action {
} }
createRelease() { createRelease() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.createdPrerelease); return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.draft, this.inputs.generateReleaseNotes, this.inputs.createdReleaseName, this.inputs.createdPrerelease);
}); });
} }
} }

View File

@@ -70,7 +70,11 @@ class CoreInputs {
return ''; return '';
} }
get commit() { get commit() {
return core.getInput('commit'); const commit = core.getInput('commit');
if (commit) {
return commit;
}
return undefined;
} }
get createdReleaseName() { get createdReleaseName() {
if (CoreInputs.omitName) if (CoreInputs.omitName)
@@ -98,6 +102,10 @@ class CoreInputs {
const draft = core.getInput('draft'); const draft = core.getInput('draft');
return draft == 'true'; return draft == 'true';
} }
get generateReleaseNotes() {
const generate = core.getInput('generateReleaseNotes');
return generate == 'true';
}
get owner() { get owner() {
let owner = core.getInput('owner'); let owner = core.getInput('owner');
if (owner) { if (owner) {

View File

@@ -15,7 +15,7 @@ class GithubReleases {
this.inputs = inputs; this.inputs = inputs;
this.git = git; this.git = git;
} }
create(tag, body, commitHash, discussionCategory, draft, name, prerelease) { create(tag, body, commitHash, discussionCategory, draft, generateReleaseNotes, name, prerelease) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// noinspection TypeScriptValidateJSTypes // noinspection TypeScriptValidateJSTypes
return this.git.rest.repos.createRelease({ return this.git.rest.repos.createRelease({
@@ -23,6 +23,7 @@ class GithubReleases {
name: name, name: name,
discussion_category_name: discussionCategory, discussion_category_name: discussionCategory,
draft: draft, draft: draft,
generate_release_notes: generateReleaseNotes,
owner: this.inputs.owner, owner: this.inputs.owner,
prerelease: prerelease, prerelease: prerelease,
repo: this.inputs.repo, repo: this.inputs.repo,

View File

@@ -3,11 +3,11 @@
"version": "1.1.0", "version": "1.1.0",
"private": true, "private": true,
"description": "An action which manages a github release", "description": "An action which manages a github release",
"main": "dist/index.js", "main": "lib/main.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"clean": "rm -rf lib/*", "clean": "rm -rf lib/*",
"debug": "yarn clean && yarn install && yarn build", "debug": "yarn clean && yarn install && yarn build && yarn package",
"package": "ncc build --source-map --license licenses.txt", "package": "ncc build --source-map --license licenses.txt",
"release": "yarn clean && yarn install --production && yarn build && yarn package", "release": "yarn clean && yarn install --production && yarn build && yarn package",
"test": "jest" "test": "jest"

View File

@@ -114,6 +114,7 @@ export class Action {
this.inputs.commit, this.inputs.commit,
this.inputs.discussionCategory, this.inputs.discussionCategory,
this.inputs.draft, this.inputs.draft,
this.inputs.generateReleaseNotes,
this.inputs.createdReleaseName, this.inputs.createdReleaseName,
this.inputs.createdPrerelease this.inputs.createdPrerelease
) )

View File

@@ -8,11 +8,12 @@ export interface Inputs {
readonly allowUpdates: boolean readonly allowUpdates: boolean
readonly artifactErrorsFailBuild: boolean readonly artifactErrorsFailBuild: boolean
readonly artifacts: Artifact[] readonly artifacts: Artifact[]
readonly commit: string readonly commit?: string
readonly createdReleaseBody?: string readonly createdReleaseBody?: string
readonly createdReleaseName?: string readonly createdReleaseName?: string
readonly discussionCategory?: string readonly discussionCategory?: string
readonly draft: boolean readonly draft: boolean
readonly generateReleaseNotes: boolean
readonly owner: string readonly owner: string
readonly createdPrerelease: boolean readonly createdPrerelease: boolean
readonly removeArtifacts: boolean readonly removeArtifacts: boolean
@@ -83,8 +84,12 @@ export class CoreInputs implements Inputs {
return '' return ''
} }
get commit(): string { get commit(): string | undefined {
return core.getInput('commit') const commit = core.getInput('commit')
if (commit) {
return commit
}
return undefined
} }
get createdReleaseName(): string | undefined { get createdReleaseName(): string | undefined {
@@ -117,6 +122,11 @@ export class CoreInputs implements Inputs {
const draft = core.getInput('draft') const draft = core.getInput('draft')
return draft == 'true' return draft == 'true'
} }
get generateReleaseNotes(): boolean {
const generate = core.getInput('generateReleaseNotes')
return generate == 'true'
}
get owner(): string { get owner(): string {
let owner = core.getInput('owner') let owner = core.getInput('owner')

View File

@@ -24,6 +24,7 @@ export interface Releases {
commitHash?: string, commitHash?: string,
discussionCategory?: string, discussionCategory?: string,
draft?: boolean, draft?: boolean,
generateReleaseNotes?: boolean,
name?: string, name?: string,
prerelease?: boolean prerelease?: boolean
): Promise<CreateReleaseResponse> ): Promise<CreateReleaseResponse>
@@ -72,6 +73,7 @@ export class GithubReleases implements Releases {
commitHash?: string, commitHash?: string,
discussionCategory?: string, discussionCategory?: string,
draft?: boolean, draft?: boolean,
generateReleaseNotes?: boolean,
name?: string, name?: string,
prerelease?: boolean prerelease?: boolean
): Promise<CreateReleaseResponse> { ): Promise<CreateReleaseResponse> {
@@ -81,6 +83,7 @@ export class GithubReleases implements Releases {
name: name, name: name,
discussion_category_name: discussionCategory, discussion_category_name: discussionCategory,
draft: draft, draft: draft,
generate_release_notes: generateReleaseNotes,
owner: this.inputs.owner, owner: this.inputs.owner,
prerelease: prerelease, prerelease: prerelease,
repo: this.inputs.repo, repo: this.inputs.repo,

View File

@@ -1,7 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"moduleResolution": "node",
"outDir": "./lib", /* Redirect output structure to the directory. */ "outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */ "strict": true, /* Enable all strict type-checking options. */