Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unit tests #45

Merged
merged 17 commits into from
Jan 21, 2022
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dist/
lib/
node_modules/
src/functions/__mocks__
jest.config.js
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
workflow_dispatch:
push:
branches: [main]
pull_request_target:
pull_request:
branches: [main]

jobs:
Expand Down
58 changes: 36 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,36 @@

This Action automatically creates and/or updates release drafts.
* Generates & updates release notes using GitHub's Auto-generate release notes functionality. More info [here](https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes).
* Draft tag defaults to previous semver compliant tag +1 patch.
* Draft tag defaults to previous semver compliant tag +1 patch. See inputs for more info.

## Usage

### Pre-requisites
Create a workflow `.yml` file in your repository's `.github/workflows` directory. An [example workflow](#example-workflow) is available below. For more information, reference the GitHub Help Documentation for [Creating a workflow file](https://help.github.com/en/articles/configuring-a-workflow#creating-a-workflow-file).

### Inputs
Inputs are defined in [`action.yml`](action.yml):

* `repo-token` - The GITHUB_TOKEN secret.
* `commitish` - Release target. Default: `main` branch.
* `bump` - NOT AVAILABLE. Semver bump type. Options: major, minor, patch, prerelease. Default: patch.
| Name | Required | Description | Default |
| ---- | -------- | ----------- | ------- |
| `repo-token` | `Yes`| Token to use to authenticate with GitHub API. [GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret) suggested. | N/A |
| `commitish` | `No` | Target of release. | Default branch |
| `bump` | `No` | Version increase type. Options: `major`, `minor`, `patch`, `premajor`, `preminor`, `prepatch`, or `prerelease`. | `patch`

### Outputs
Inputs are defined in [`action.yml`](action.yml):

* `id` - The ID of the created Release.
* `html_url` - The URL users can navigate to in order to view the release.
* `upload_url` - The URL for uploading assets to the release.
| Name | Description |
| ---- | ----------- |
| `id` | The ID of the created Release. |
| `html_url` | The URL users can navigate to in order to view the release. |
| `upload_url` | The URL for uploading assets to the release. |

### Example workflow

```yaml
# .github/workflows/release-draft.yml

name: Release Draft

on:
Expand All @@ -47,7 +55,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Release Draft
uses: crs-k/release-draft@v0.3.3
uses: crs-k/release-draft@v0.4.0
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
```
Expand All @@ -61,19 +69,25 @@ More info [here](https://docs.github.com/en/repositories/releasing-projects-on-g
changelog:
exclude:
labels:
- ignore-for-release
authors:
- octocat
- "ignore for release ✂️"
categories:
- title: Breaking Changes 🛠
labels:
- Semver-Major
- breaking-change
- title: Exciting New Features 🎉
labels:
- Semver-Minor
- enhancement
- title: Other Changes
labels:
- "*"
- title: ☄️ Breaking Changes
labels:
- "breaking change ☄️"
- title: 🎉 New Features
labels:
- "enhancement 💎"
- title: 🐛 Bug Fixes
labels:
- "bug 🐛"
- title: 🧰 Maintenance
labels:
- "chore 🧹"
- "dependencies 🛠"
- title: 📓 Documentation
labels:
- "documentation 📓"
- title: 🃏 Miscellaneous
labels:
- "*"
```
20 changes: 20 additions & 0 deletions __mocks__/@actions/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const context = {
repo: {
owner: 'owner',
repo: 'repo'
}
}

const github = {
rest: {
repos: {
get: jest.fn(),
listReleases: jest.fn(),
generateReleaseNotes: jest.fn(),
updateRelease: jest.fn(),
createRelease: jest.fn()
}
}
}

export const getOctokit = jest.fn().mockImplementation(() => github)
36 changes: 36 additions & 0 deletions __tests__/functions/create-draft.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
jest.mock('@actions/core')
jest.mock('../../src/functions/get-default-branch')

const core = require('@actions/core')
import {createDraft} from '../../src/functions/create-draft'
import {github} from '../../src/functions/get-context'

jest.mock('../../src/functions/get-context')
let targetTag = 'v1.0.0'
let commitish = 'main'

describe('Create Draft Function', () => {
test('createRelease endpoint is called', async () => {
await createDraft(targetTag)

expect(github.rest.repos.createRelease).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo',
tag_name: targetTag,
name: targetTag,
target_commitish: commitish,
draft: true,
generate_release_notes: true
})
})

test('Infos are set', async () => {
core.info = jest.fn()
await createDraft(targetTag)

expect(core.info).toHaveBeenNthCalledWith(1, 'Creating Release Draft...')
expect(core.info).toHaveBeenNthCalledWith(2, `Release ID: '0'`)
expect(core.info).toHaveBeenNthCalledWith(3, `HTML URL: ''`)
expect(core.info).toHaveBeenNthCalledWith(4, `Upload URL: ''`)
})
})
30 changes: 30 additions & 0 deletions __tests__/functions/create-next-tag.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
jest.mock('@actions/core')

const core = require('@actions/core')
import {createNextTag} from '../../src/functions/create-next-tag'

describe('Create Next Tag Function', () => {
test('Infos are set (semver compliant tag)', async () => {
let targetTag = 'v1.2.3'
core.info = jest.fn()
await createNextTag(targetTag)

expect(core.info).toHaveBeenNthCalledWith(1, 'Generating Next tag...')
expect(core.info).toHaveBeenNthCalledWith(2, `Bump Type: patch`)
expect(core.info).toHaveBeenNthCalledWith(3, `Next tag: v1.2.4`)
})

test('Infos are set (semver noncompliant tag)', async () => {
let targetTag = 'BAD'
core.info = jest.fn()
await createNextTag(targetTag)

expect(core.info).toHaveBeenNthCalledWith(1, 'Generating Next tag...')
expect(core.info).toHaveBeenNthCalledWith(
2,
`Next tag failed to generate. Defaulting to v0.1.0`
)
expect(core.info).toHaveBeenNthCalledWith(3, `Bump Type: patch`)
expect(core.info).toHaveBeenNthCalledWith(4, `Next tag: v0.1.0`)
})
})
35 changes: 35 additions & 0 deletions __tests__/functions/create-notes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
jest.mock('@actions/core')
jest.mock('@actions/github')
jest.mock('assert')

const core = require('@actions/core')
import {createNotes} from '../../src/functions/create-notes'
import {github} from '../../src/functions/get-context'

jest.mock('../../src/functions/get-context')
let targetTag = 'v1.0.0'

describe('Create Notes Function', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('createNotes endpoint is called', async () => {
await createNotes(targetTag)

expect(github.rest.repos.generateReleaseNotes).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo',
tag_name: targetTag
})
})

test('Infos are set', async () => {
core.info = jest.fn()
await createNotes(targetTag)

expect(core.info).toHaveBeenNthCalledWith(1, 'Generating Release Notes...')
expect(core.info).toHaveBeenNthCalledWith(2, `Release Notes failed to generate.`)
expect(core.info).toHaveBeenNthCalledWith(3, `Generated name: 'Unnamed'`)
expect(core.info).toHaveBeenNthCalledWith(4, `Generated body: 'Unnamed'`)
})
})
12 changes: 12 additions & 0 deletions __tests__/functions/get-context.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
jest.mock('@actions/core')

const core = require('@actions/core')
import {github, owner, repo} from '../../src/functions/get-context'

describe('Get Context Function', () => {
test('Mock context check', async () => {
expect(github).toBeTruthy
expect(owner).toBe('owner')
expect(repo).toBe('repo')
})
})
32 changes: 32 additions & 0 deletions __tests__/functions/get-default-branch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
jest.mock('@actions/core')
jest.mock('@actions/github')
jest.mock('assert')

const core = require('@actions/core')
const branch = require('../../src/functions/get-default-branch')
import {getDefaultBranch} from '../../src/functions/get-default-branch'
import {github} from '../../src/functions/get-context'

jest.mock('../../src/functions/get-context')

describe('Get Default Branch Function', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('getDefaultBranch endpoint is called', async () => {
await getDefaultBranch()

expect(github.rest.repos.get).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo'
})
})

test('Infos are set', async () => {
core.info = jest.fn()
await getDefaultBranch()

expect(core.info).toHaveBeenNthCalledWith(1, 'Retrieving the default branch name...')
expect(core.info).toHaveBeenNthCalledWith(2, `Default branch: ''`)
})
})
39 changes: 39 additions & 0 deletions __tests__/functions/get-recent-release.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
jest.mock('@actions/core')
jest.mock('@actions/github')
jest.mock('assert')

const core = require('@actions/core')
import {getRecentRelease} from '../../src/functions/get-recent-release'
import {github} from '../../src/functions/get-context'

jest.mock('../../src/functions/get-context')

describe('Get Recent Release Function', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('listReleases endpoint is called', async () => {
await getRecentRelease()

expect(github.rest.repos.listReleases).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo',
per_page: 1,
page: 1
})
})

test('Infos are set', async () => {
core.info = jest.fn()
await getRecentRelease()

expect(core.info).toHaveBeenNthCalledWith(1, 'Retrieving the most recent release...')
expect(core.info).toHaveBeenNthCalledWith(
2,
`Previous release cannot be found with reason Cannot read properties of undefined (reading 'data'). Defaulting tag.`
)
expect(core.info).toHaveBeenNthCalledWith(3, `Tag Name: '0.1.0'`)
expect(core.info).toHaveBeenNthCalledWith(4, `Draft: 'false'`)
expect(core.info).toHaveBeenNthCalledWith(5, `Release ID: '0'`)
})
})
52 changes: 52 additions & 0 deletions __tests__/functions/update-draft.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
jest.mock('@actions/core')
jest.mock('@actions/github')
jest.mock('assert')

const core = require('@actions/core')
import {updateDraft} from '../../src/functions/update-draft'
import {github} from '../../src/functions/get-context'

jest.mock('../../src/functions/get-context')
let targetTag = 'v1.0.0'
let updateName = 'updateName'
let updateBody = 'updateBody'
let prevReleaseId = 0

describe('Update Draft Function', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('updateDraft endpoint is called', async () => {
await updateDraft(targetTag, updateName, updateBody, prevReleaseId)

expect(github.rest.repos.updateRelease).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo',
release_id: prevReleaseId,
tag_name: targetTag,
name: updateName,
body: updateBody,
draft: true
})
})

test('Infos are set', async () => {
core.info = jest.fn()
await updateDraft(targetTag, updateName, updateBody, prevReleaseId)

expect(core.info).toHaveBeenNthCalledWith(1, 'Updating Release Draft...')
expect(core.info).toHaveBeenNthCalledWith(2, `Release ID: '0'`)
expect(core.info).toHaveBeenNthCalledWith(3, `HTML URL: ''`)
expect(core.info).toHaveBeenNthCalledWith(4, `Upload URL: ''`)
})

/* test('Outputs are set', async () => {
core.output = jest.fn()
await updateDraft(targetTag, updateName, updateBody, prevReleaseId)

expect(core.output).toHaveBeenNthCalledWith(1, 'Updating Release Draft...')
expect(core.output).toHaveBeenNthCalledWith(2, `Release ID: '0'`)
expect(core.output).toHaveBeenNthCalledWith(3, `HTML URL: ''`)
expect(core.output).toHaveBeenNthCalledWith(4, `Upload URL: ''`)
}) */
})
Loading