diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 169ae1d..e3fa48b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -25,19 +25,20 @@ jobs: npm run test:cov - name: Report coverage if: always() - uses: slavcodev/coverage-monitor-action@1.1.0 + uses: slavcodev/coverage-monitor-action@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} - clover_file: coverage/clover.xml + coverage_path: coverage/clover.xml threshold_alert: 50 threshold_warning: 75 comment_mode: update - name: Save Code Linting Report JSON if: always() run: npm run lint:report + continue-on-error: true - name: Annotate Code Linting Results if: always() - uses: ataylorme/eslint-annotate-action@1.0.4 + uses: ataylorme/eslint-annotate-action@v2 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' report-json: 'eslint_report.json' diff --git a/src/github.js b/src/github.js index 4a0c361..7c55f73 100644 --- a/src/github.js +++ b/src/github.js @@ -69,6 +69,26 @@ export default function githubFactory(token, repository) { }); }); }, + /** + * Create the release pull request + * @param {String} repo - owner and name of the repository + * @param {Number} number - issue number + * @param {String[]} label - label name + * @returns {Promise} - resolves with the add label data, if the label is added + */ + addLabel(repo, number, label) { + const ghpr = client.issue(repo, number); + return new Promise((resolve, reject) => { + ghpr.addLabels({ + labels: label + }, (err, data) => { + if (err) { + return reject(err); + } + return resolve(data); + }); + }); + }, /** * Create the release pull request @@ -341,4 +361,4 @@ export default function githubFactory(token, repository) { .reduce((acc, note) => note ? `${acc} - ${note}\n` : acc, ''); } }; -} +} \ No newline at end of file diff --git a/src/release.js b/src/release.js index a882a59..1d97c13 100644 --- a/src/release.js +++ b/src/release.js @@ -30,7 +30,7 @@ import configFactory from './config.js'; import github from './github.js'; import gitClientFactory from './git.js'; import log from './log.js'; -import conventionalCommits from './conventionalCommits.js'; +import conventionalCommits from './conventionalCommits.js'; import semverValid from 'semver/functions/valid.js'; import extension from './release/extensionApi.js'; @@ -233,17 +233,18 @@ export default function taoExtensionReleaseFactory(params = {}) { releaseBranch, data.version, data.lastVersion, - subjectType + subjectType, ); - if (pullRequest && pullRequest.state === 'open') { data.pr = { url: pullRequest.html_url, apiUrl: pullRequest.url, number: pullRequest.number, - id: pullRequest.id + id: pullRequest.id, + full_name: pullRequest.head.repo.full_name, }; - + const labels = ['releases']; + await githubClient.addLabel(data.pr.full_name, data.pr.number, labels); log.info(`${data.pr.url} created`); log.done(); } else { @@ -614,7 +615,7 @@ export default function taoExtensionReleaseFactory(params = {}) { } = await conventionalCommits.getNextVersion(lastTag); if (releaseVersion) { - if(!semverGt(releaseVersion, lastVersion)) { + if (!semverGt(releaseVersion, lastVersion)) { log.exit(`The provided version is lesser than the latest version ${lastVersion}.`); } log.info(`Release version provided: ${releaseVersion}`); @@ -622,10 +623,10 @@ export default function taoExtensionReleaseFactory(params = {}) { if (interactive) { if (recommendation.stats && recommendation.stats.commits === 0) { - const { releaseAgain } = await inquirer.prompt({ + const { releaseAgain } = await inquirer.prompt({ type: 'confirm', name: 'releaseAgain', - default : false, + default: false, message: 'There\'s no new commits, do you really want to release a new version?' }); @@ -634,7 +635,7 @@ export default function taoExtensionReleaseFactory(params = {}) { } } else if (recommendation.stats && recommendation.stats.unset > 0) { - const { acceptDefaultVersion } = await inquirer.prompt({ + const { acceptDefaultVersion } = await inquirer.prompt({ type: 'confirm', name: 'acceptDefaultVersion', message: recommendation.stats.unset === recommendation.stats.commits ? @@ -686,4 +687,4 @@ export default function taoExtensionReleaseFactory(params = {}) { await gitClient.commitAndPush(data.releasingBranch, 'chore: bump version'); } }; -} +} \ No newline at end of file diff --git a/tests/unit/release/createPullRequest/release.spec.js b/tests/unit/release/createPullRequest/release.spec.js index bed1cca..f7b3642 100644 --- a/tests/unit/release/createPullRequest/release.spec.js +++ b/tests/unit/release/createPullRequest/release.spec.js @@ -36,6 +36,7 @@ jest.mock('../../../../src/github.js', () => { ...originalModule, default: jest.fn(() => ({ createReleasePR: jest.fn(), + addLabel: jest.fn(() => { }), release: jest.fn(), extractReleaseNotesFromReleasePR: jest.fn() })) @@ -67,7 +68,7 @@ afterAll(() => { }); describe('src/release.js createPullRequest', () => { - + test('should define createPullRequest method on release instance', () => { expect.assertions(1); @@ -100,17 +101,26 @@ describe('src/release.js createPullRequest', () => { expect.assertions(2); const url = 'testUrl'; - const release = releaseFactory({ branchPrefix, releaseBranch }); jest.spyOn(release, 'getMetadata').mockImplementationOnce(() => ({ repoName })); const createReleasePR = jest.fn(() => ({ state: 'open', html_url: url, + url: 'apiUrl', + number: 42, + id: 'pr_id', + head: { + repo: { + full_name: 'fullName' + } + } })); + const addLabel = jest.fn(); github.mockImplementationOnce(() => { //Mock the default export return { - createReleasePR + createReleasePR, + addLabel }; }); @@ -125,29 +135,36 @@ describe('src/release.js createPullRequest', () => { test('should set data.pr', async () => { expect.assertions(1); - const html_url = 'testUrl'; - const apiUrl = 'apiUrl'; + const html_url = 'apiUrl'; const number = 42; const id = 'pr_id'; const expectedPR = { - url: html_url, - apiUrl, - number, - id + url: 'apiUrl', + apiUrl: 'apiUrl', + number: 42, + id: 'pr_id', + full_name: 'fullName' }; const release = releaseFactory({ branchPrefix, releaseBranch }); jest.spyOn(release, 'getMetadata').mockImplementationOnce(() => ({ repoName })); const createReleasePR = jest.fn(() => ({ state: 'open', - html_url, - url: apiUrl, + html_url: html_url, + url: html_url, number, - id + id, + head: { + repo: { + full_name: 'fullName' + } + } })); + const addLabel = jest.fn(); github.mockImplementationOnce(() => { //Mock the default export return { - createReleasePR + createReleasePR, + addLabel }; }); @@ -165,11 +182,22 @@ describe('src/release.js createPullRequest', () => { jest.spyOn(release, 'getMetadata').mockImplementationOnce(() => ({ repoName })); const createReleasePR = jest.fn(() => ({ state: 'open', + html_url: 'apiUrl', + url: 'apiUrl', + number: 42, + id: 'pr_id', + head: { + repo: { + full_name: 'fullName' + } + } })); + const addLabel = jest.fn(); github.mockImplementationOnce(() => { //Mock the default export return { - createReleasePR + createReleasePR, + addLabel }; }); @@ -193,4 +221,4 @@ describe('src/release.js createPullRequest', () => { expect(log.exit).toBeCalledTimes(1); expect(log.exit).toBeCalledWith('Unable to create the release pull request'); }); -}); +}); \ No newline at end of file diff --git a/tests/unit/release/mergePullRequest/release.spec.js b/tests/unit/release/mergePullRequest/release.spec.js index c7f4bf9..f934c25 100644 --- a/tests/unit/release/mergePullRequest/release.spec.js +++ b/tests/unit/release/mergePullRequest/release.spec.js @@ -57,7 +57,19 @@ jest.mock('../../../../src/github.js', () => { __esModule: true, ...originalModule, default: jest.fn(() => ({ - createReleasePR: jest.fn(() => ({ state: 'open' })), + createReleasePR: jest.fn(() => ({ + state: 'open', + html_url: 'apiUrl', + url: 'apiUrl', + number: 42, + id: 'pr_id', + head: { + repo: { + full_name: 'fullName' + } + } + })), + addLabel: jest.fn(() => { }), release: jest.fn(), extractReleaseNotesFromReleasePR: jest.fn() })) @@ -71,13 +83,13 @@ jest.mock('../../../../src/git.js', () => { __esModule: true, ...originalModule, default: jest.fn(() => ({ - tag: jest.fn(arg => arg), - localBranch: jest.fn(arg => arg), - push: jest.fn(arg => arg), - hasBranch: jest.fn(), + tag: jest.fn(arg => arg), + localBranch: jest.fn(arg => arg), + push: jest.fn(arg => arg), + hasBranch: jest.fn(), hasTag: jest.fn(), getLastTag: jest.fn(), - hasDiff: jest.fn(() => true), + hasDiff: jest.fn(() => true), mergeBack: jest.fn(), pull: jest.fn(), merge: jest.fn(), @@ -118,15 +130,15 @@ describe('src/release.js mergePullRequest', () => { jest.clearAllMocks(); jest.useRealTimers(); }); - + test('should define mergePullRequest method on release instance', () => { expect.assertions(1); - + const release = releaseFactory({ baseBranch, releaseBranch }); release.setData({ releasingBranch, token, extension: {} }); expect(typeof release.mergePullRequest).toBe('function'); }); - + test('should open pull request in browser', async () => { expect.assertions(1); @@ -223,4 +235,4 @@ describe('src/release.js mergePullRequest', () => { expect(log.done).toBeCalledTimes(2); expect(log.done).toBeCalledWith('PR merged'); }); -}); +}); \ No newline at end of file