From 8041c9dd736617dcd11d2b4e975395d9f378c280 Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Sat, 26 Oct 2019 00:15:08 +1100 Subject: [PATCH 1/4] Implement release replacement --- action.yml | 4 +++ dist/index.js | 62 ++++++++++++++++++++++++++++++++++-- src/create-release.js | 58 +++++++++++++++++++++++++++++++++ tests/create-release.test.js | 47 +++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 59ebbb81..05faf7e2 100644 --- a/action.yml +++ b/action.yml @@ -8,6 +8,10 @@ inputs: release_name: description: 'The name of the release. For example, `Release v1.0.1`' required: true + replace_old_tag: + description: 'Whether to delete an older tag (not for this commit) if the same tag name is found' + required: false + default: false draft: description: '`true` to create a draft (unpublished) release, `false` to create a published one. Default: `false`' required: false diff --git a/dist/index.js b/dist/index.js index 08b7fb49..61f420e1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1697,7 +1697,7 @@ module.exports = require("https"); /***/ 215: /***/ (function(module) { -module.exports = {"_from":"@octokit/rest@^16.15.0","_id":"@octokit/rest@16.28.8","_inBundle":false,"_integrity":"sha512-FouTTcLdT++gwgKVnBN8CEVeFvY/OKzeaoH/L9LBvZhbjUotLthFWAdKa8WeOMt5x7Rs7uvBpu7IdcrtRD3wBA==","_location":"/@octokit/rest","_phantomChildren":{"os-name":"3.1.0"},"_requested":{"type":"range","registry":true,"raw":"@octokit/rest@^16.15.0","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"^16.15.0","saveSpec":null,"fetchSpec":"^16.15.0"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.28.8.tgz","_shasum":"9b57829084892a67654eaac075e1860bdd4b9419","_spec":"@octokit/rest@^16.15.0","_where":"/Users/IAmHughes/github/repos/actions-release/.github/actions/actions-release/node_modules/@actions/github","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundleDependencies":false,"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/request":"^5.0.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^3.0.0"},"deprecated":false,"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/fixtures-server":"^5.0.1","@octokit/routes":"20.9.2","@types/node":"^12.0.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.0.0","coveralls":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^2.1.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^3.0.0","nock":"^10.0.0","npm-run-all":"^4.1.2","nyc":"^14.0.0","prettier":"^1.14.2","proxy":"^0.2.4","semantic-release":"^15.0.0","sinon":"^7.2.4","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","standard":"^14.0.2","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"node scripts/generate-types","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","generate-routes":"node scripts/generate-routes","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"standard","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","test:memory":"mocha test/memory-test","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect","cy"],"ignore":["/docs"]},"types":"index.d.ts","version":"16.28.8"}; +module.exports = {"_args":[["@octokit/rest@16.28.8","/home/victor/Documents/Apps/create-release"]],"_from":"@octokit/rest@16.28.8","_id":"@octokit/rest@16.28.8","_inBundle":false,"_integrity":"sha512-FouTTcLdT++gwgKVnBN8CEVeFvY/OKzeaoH/L9LBvZhbjUotLthFWAdKa8WeOMt5x7Rs7uvBpu7IdcrtRD3wBA==","_location":"/@octokit/rest","_phantomChildren":{"os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.28.8","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.28.8","saveSpec":null,"fetchSpec":"16.28.8"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.28.8.tgz","_spec":"16.28.8","_where":"/home/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/request":"^5.0.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^3.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/fixtures-server":"^5.0.1","@octokit/routes":"20.9.2","@types/node":"^12.0.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.0.0","coveralls":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^2.1.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^3.0.0","nock":"^10.0.0","npm-run-all":"^4.1.2","nyc":"^14.0.0","prettier":"^1.14.2","proxy":"^0.2.4","semantic-release":"^15.0.0","sinon":"^7.2.4","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","standard":"^14.0.2","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"node scripts/generate-types","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","generate-routes":"node scripts/generate-routes","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"standard","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","test:memory":"mocha test/memory-test","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect","cy"],"ignore":["/docs"]},"types":"index.d.ts","version":"16.28.8"}; /***/ }), @@ -3796,7 +3796,7 @@ function octokitRestNormalizeGitReferenceResponses (octokit) { /***/ 314: /***/ (function(module) { -module.exports = {"_from":"@octokit/graphql@^2.0.1","_id":"@octokit/graphql@2.1.3","_inBundle":false,"_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_location":"/@octokit/graphql","_phantomChildren":{},"_requested":{"type":"range","registry":true,"raw":"@octokit/graphql@^2.0.1","name":"@octokit/graphql","escapedName":"@octokit%2fgraphql","scope":"@octokit","rawSpec":"^2.0.1","saveSpec":null,"fetchSpec":"^2.0.1"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_shasum":"60c058a0ed5fa242eca6f938908d95fd1a2f4b92","_spec":"@octokit/graphql@^2.0.1","_where":"/Users/IAmHughes/github/repos/actions-release/.github/actions/actions-release/node_modules/@actions/github","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"bundleDependencies":false,"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"deprecated":false,"description":"GitHub GraphQL API client for browsers and Node","devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"files":["lib"],"homepage":"https://github.com/octokit/graphql.js#readme","keywords":["octokit","github","api","graphql"],"license":"MIT","main":"index.js","name":"@octokit/graphql","publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/graphql.js.git"},"scripts":{"build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","prebuild":"mkdirp dist/","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"version":"2.1.3"}; +module.exports = {"_args":[["@octokit/graphql@2.1.3","/home/victor/Documents/Apps/create-release"]],"_from":"@octokit/graphql@2.1.3","_id":"@octokit/graphql@2.1.3","_inBundle":false,"_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_location":"/@octokit/graphql","_phantomChildren":{},"_requested":{"type":"version","registry":true,"raw":"@octokit/graphql@2.1.3","name":"@octokit/graphql","escapedName":"@octokit%2fgraphql","scope":"@octokit","rawSpec":"2.1.3","saveSpec":null,"fetchSpec":"2.1.3"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_spec":"2.1.3","_where":"/home/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"description":"GitHub GraphQL API client for browsers and Node","devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"files":["lib"],"homepage":"https://github.com/octokit/graphql.js#readme","keywords":["octokit","github","api","graphql"],"license":"MIT","main":"index.js","name":"@octokit/graphql","publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/graphql.js.git"},"scripts":{"build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","prebuild":"mkdirp dist/","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"version":"2.1.3"}; /***/ }), @@ -7861,9 +7861,67 @@ async function run() { // This removes the 'refs/tags' portion of the string, i.e. from 'refs/tags/v1.10.15' to 'v1.10.15' const tag = tagName.replace('refs/tags/', ''); const releaseName = core.getInput('release_name', { required: true }).replace('refs/tags/', ''); + const replaceOldTag = core.getInput('replace_old_tag', { required: false }) === 'true'; const draft = core.getInput('draft', { required: false }) === 'true'; const prerelease = core.getInput('prerelease', { required: false }) === 'true'; + if (replaceOldTag) { + // Check to see if we need to replace an older release + + try { + // Get a single reference + // API Documentation: https://developer.github.com/v3/git/refs/#get-a-single-reference + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-git-get-ref + const getRefResponse = await github.git.getRef({ + owner, + repo, + ref: `tags/${tag}` + }); + + console.log(getRefResponse); + const refSha = getRefResponse.data.object.sha; + if (refSha !== process.env.GITHUB_SHA) { + // Delete the tag and release associated with this release + + // Get a release by tag name + // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag + const getReleaseResponse = await github.repos.getReleaseByTag({ + owner, + repo, + tag + }); + + const releaseId = getReleaseResponse.data.id; + + // Delete a release + // API Documentation: https://developer.github.com/v3/repos/releases/#delete-a-release + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-delete-release + await github.repos.deleteRelease({ + owner, + repo, + release_id: releaseId + }); + + // Delete a reference + // API Documentation: https://developer.github.com/v3/git/refs/#delete-a-reference + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-git-delete-ref + await github.git.deleteRef({ + owner, + repo, + ref: `tags/${tag}` + }); + } + } catch (error) { + // If this is a 404 then we should be okay to continue on + // It just means that the release has not been created + + if (error.status !== 404) { + throw error; + } + } + } + // Create a release // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release diff --git a/src/create-release.js b/src/create-release.js index df488b4c..18a9e097 100644 --- a/src/create-release.js +++ b/src/create-release.js @@ -15,9 +15,67 @@ async function run() { // This removes the 'refs/tags' portion of the string, i.e. from 'refs/tags/v1.10.15' to 'v1.10.15' const tag = tagName.replace('refs/tags/', ''); const releaseName = core.getInput('release_name', { required: true }).replace('refs/tags/', ''); + const replaceOldTag = core.getInput('replace_old_tag', { required: false }) === 'true'; const draft = core.getInput('draft', { required: false }) === 'true'; const prerelease = core.getInput('prerelease', { required: false }) === 'true'; + if (replaceOldTag) { + // Check to see if we need to replace an older release + + try { + // Get a single reference + // API Documentation: https://developer.github.com/v3/git/refs/#get-a-single-reference + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-git-get-ref + const getRefResponse = await github.git.getRef({ + owner, + repo, + ref: `tags/${tag}` + }); + + console.log(getRefResponse); + const refSha = getRefResponse.data.object.sha; + if (refSha !== process.env.GITHUB_SHA) { + // Delete the tag and release associated with this release + + // Get a release by tag name + // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag + const getReleaseResponse = await github.repos.getReleaseByTag({ + owner, + repo, + tag + }); + + const releaseId = getReleaseResponse.data.id; + + // Delete a release + // API Documentation: https://developer.github.com/v3/repos/releases/#delete-a-release + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-delete-release + await github.repos.deleteRelease({ + owner, + repo, + release_id: releaseId + }); + + // Delete a reference + // API Documentation: https://developer.github.com/v3/git/refs/#delete-a-reference + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-git-delete-ref + await github.git.deleteRef({ + owner, + repo, + ref: `tags/${tag}` + }); + } + } catch (error) { + // If this is a 404 then we should be okay to continue on + // It just means that the release has not been created + + if (error.status !== 404) { + throw error; + } + } + } + // Create a release // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release diff --git a/tests/create-release.test.js b/tests/create-release.test.js index b67c3bcd..6000161d 100644 --- a/tests/create-release.test.js +++ b/tests/create-release.test.js @@ -38,6 +38,7 @@ describe('Create Release', () => { .mockReturnValueOnce('refs/tags/v1.0.0') .mockReturnValueOnce('myRelease') .mockReturnValueOnce('false') + .mockReturnValueOnce('false') .mockReturnValueOnce('false'); await run(); @@ -57,6 +58,7 @@ describe('Create Release', () => { .fn() .mockReturnValueOnce('refs/tags/v1.0.0') .mockReturnValueOnce('myRelease') + .mockReturnValueOnce('false') .mockReturnValueOnce('true') .mockReturnValueOnce('false'); @@ -78,6 +80,7 @@ describe('Create Release', () => { .mockReturnValueOnce('refs/tags/v1.0.0') .mockReturnValueOnce('myRelease') .mockReturnValueOnce('false') + .mockReturnValueOnce('false') .mockReturnValueOnce('true'); await run(); @@ -92,12 +95,55 @@ describe('Create Release', () => { }); }); + test('Create release endpoint is called when an existing tag does not exist', async () => { + core.getInput = jest + .fn() + .mockReturnValueOnce('refs/tags/v1.0.0') + .mockReturnValueOnce('myRelease') + .mockReturnValueOnce('true') + .mockReturnValueOnce('false') + .mockReturnValueOnce('false'); + + await run(); + + expect(createRelease).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + tag_name: 'v1.0.0', + name: 'myRelease', + draft: false, + prerelease: false + }); + }); + + test('Older release is deleted', async () => { + core.getInput = jest + .fn() + .mockReturnValueOnce('refs/tags/v1.0.0') + .mockReturnValueOnce('myRelease') + .mockReturnValueOnce('true') + .mockReturnValueOnce('false') + .mockReturnValueOnce('false'); + + await run(); + + expect(createRelease).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + tag_name: 'v1.0.0', + name: 'myRelease', + draft: false, + prerelease: false + }); + }); + test('Outputs are set', async () => { core.getInput = jest .fn() .mockReturnValueOnce('refs/tags/v1.0.0') .mockReturnValueOnce('myRelease') .mockReturnValueOnce('false') + .mockReturnValueOnce('false') .mockReturnValueOnce('false'); core.setOutput = jest.fn(); @@ -115,6 +161,7 @@ describe('Create Release', () => { .mockReturnValueOnce('refs/tags/v1.0.0') .mockReturnValueOnce('myRelease') .mockReturnValueOnce('false') + .mockReturnValueOnce('false') .mockReturnValueOnce('false'); createRelease.mockRestore(); From 3e8166d54d7619d227905259206dde51501c1d39 Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Sat, 26 Oct 2019 00:16:59 +1100 Subject: [PATCH 2/4] Add unit tests for release replacement --- dist/index.js | 1 - src/create-release.js | 1 - tests/create-release.test.js | 101 +++++++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 61f420e1..5943639b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7878,7 +7878,6 @@ async function run() { ref: `tags/${tag}` }); - console.log(getRefResponse); const refSha = getRefResponse.data.object.sha; if (refSha !== process.env.GITHUB_SHA) { // Delete the tag and release associated with this release diff --git a/src/create-release.js b/src/create-release.js index 18a9e097..7792da6e 100644 --- a/src/create-release.js +++ b/src/create-release.js @@ -32,7 +32,6 @@ async function run() { ref: `tags/${tag}` }); - console.log(getRefResponse); const refSha = getRefResponse.data.object.sha; if (refSha !== process.env.GITHUB_SHA) { // Delete the tag and release associated with this release diff --git a/tests/create-release.test.js b/tests/create-release.test.js index 6000161d..8061e699 100644 --- a/tests/create-release.test.js +++ b/tests/create-release.test.js @@ -7,9 +7,39 @@ const run = require('../src/create-release.js'); /* eslint-disable no-undef */ describe('Create Release', () => { + let getRef; + let deleteRef; let createRelease; + let deleteRelease; + let getReleaseByTag; beforeEach(() => { + process.env = Object.assign(process.env, { GITHUB_SHA: 'sha1234' }); + + getRef = jest.fn(obj => { + let sha = null; + + if (obj.ref === 'tags/existing') sha = 'sha1234'; + if (obj.ref === 'tags/replaceExisting') sha = 'sha2345'; + + if (sha) { + return { + data: { + object: { + sha + } + } + }; + } + + const error = { + status: 404 + }; + throw error; + }); + + deleteRef = jest.fn(); + createRelease = jest.fn().mockReturnValueOnce({ data: { id: 'releaseId', @@ -18,14 +48,28 @@ describe('Create Release', () => { } }); + deleteRelease = jest.fn(); + + getReleaseByTag = jest.fn().mockReturnValueOnce({ + data: { + id: 'releaseId' + } + }); + context.repo = { owner: 'owner', repo: 'repo' }; const github = { + git: { + getRef, + deleteRef + }, repos: { - createRelease + createRelease, + deleteRelease, + getReleaseByTag } }; @@ -95,7 +139,7 @@ describe('Create Release', () => { }); }); - test('Create release endpoint is called when an existing tag does not exist', async () => { + test('Existing release is not retrieved when tag does not exist', async () => { core.getInput = jest .fn() .mockReturnValueOnce('refs/tags/v1.0.0') @@ -106,6 +150,14 @@ describe('Create Release', () => { await run(); + expect(getRef).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + ref: 'tags/v1.0.0' + }); + + expect(getReleaseByTag).toHaveBeenCalledTimes(0); + expect(createRelease).toHaveBeenCalledWith({ owner: 'owner', repo: 'repo', @@ -116,10 +168,39 @@ describe('Create Release', () => { }); }); + test('Current release is not deleted', async () => { + core.getInput = jest + .fn() + .mockReturnValueOnce('refs/tags/existing') + .mockReturnValueOnce('myRelease') + .mockReturnValueOnce('true') + .mockReturnValueOnce('false') + .mockReturnValueOnce('false'); + + await run(); + + expect(getRef).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + ref: 'tags/existing' + }); + + expect(getReleaseByTag).toHaveBeenCalledTimes(0); + + expect(createRelease).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + tag_name: 'existing', + name: 'myRelease', + draft: false, + prerelease: false + }); + }); + test('Older release is deleted', async () => { core.getInput = jest .fn() - .mockReturnValueOnce('refs/tags/v1.0.0') + .mockReturnValueOnce('refs/tags/replaceExisting') .mockReturnValueOnce('myRelease') .mockReturnValueOnce('true') .mockReturnValueOnce('false') @@ -127,10 +208,22 @@ describe('Create Release', () => { await run(); + expect(deleteRelease).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + release_id: 'releaseId' + }); + + expect(deleteRef).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + ref: 'tags/replaceExisting' + }); + expect(createRelease).toHaveBeenCalledWith({ owner: 'owner', repo: 'repo', - tag_name: 'v1.0.0', + tag_name: 'replaceExisting', name: 'myRelease', draft: false, prerelease: false From 2d351bfdb430416dbb69bbe1694a4a29d84069a7 Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Sat, 26 Oct 2019 00:20:16 +1100 Subject: [PATCH 3/4] Document release replacement in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5df67065..448b6d20 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ For more information on these inputs, see the [API Documentation](https://develo - `tag_name`: The name of the tag for this release - `release_name`: The name of the release +- `replace_old_tag`: `true` to replace a tag of the same name if it points to another commit, `false` otherwise. Default: `false` - `draft`: `true` to create a draft (unpublished) release, `false` to create a published one. Default: `false` - `prerelease`: `true` to identify the release as a prerelease. `false` to identify the release as a full release. Default `false` From 2083a837b3c00846a96c2b342a537d0ae8924f11 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 27 Oct 2019 11:01:24 +1100 Subject: [PATCH 4/4] Fix case where an existing release already exists for a current commit --- dist/index.js | 57 ++++++++++++++++++++---------------- src/create-release.js | 53 ++++++++++++++++++--------------- tests/create-release.test.js | 21 ++++++------- 3 files changed, 73 insertions(+), 58 deletions(-) diff --git a/dist/index.js b/dist/index.js index 5943639b..6eb6ee27 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1697,7 +1697,7 @@ module.exports = require("https"); /***/ 215: /***/ (function(module) { -module.exports = {"_args":[["@octokit/rest@16.28.8","/home/victor/Documents/Apps/create-release"]],"_from":"@octokit/rest@16.28.8","_id":"@octokit/rest@16.28.8","_inBundle":false,"_integrity":"sha512-FouTTcLdT++gwgKVnBN8CEVeFvY/OKzeaoH/L9LBvZhbjUotLthFWAdKa8WeOMt5x7Rs7uvBpu7IdcrtRD3wBA==","_location":"/@octokit/rest","_phantomChildren":{"os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.28.8","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.28.8","saveSpec":null,"fetchSpec":"16.28.8"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.28.8.tgz","_spec":"16.28.8","_where":"/home/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/request":"^5.0.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^3.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/fixtures-server":"^5.0.1","@octokit/routes":"20.9.2","@types/node":"^12.0.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.0.0","coveralls":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^2.1.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^3.0.0","nock":"^10.0.0","npm-run-all":"^4.1.2","nyc":"^14.0.0","prettier":"^1.14.2","proxy":"^0.2.4","semantic-release":"^15.0.0","sinon":"^7.2.4","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","standard":"^14.0.2","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"node scripts/generate-types","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","generate-routes":"node scripts/generate-routes","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"standard","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","test:memory":"mocha test/memory-test","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect","cy"],"ignore":["/docs"]},"types":"index.d.ts","version":"16.28.8"}; +module.exports = {"_args":[["@octokit/rest@16.28.8","/Users/victor/Documents/Apps/create-release"]],"_from":"@octokit/rest@16.28.8","_id":"@octokit/rest@16.28.8","_inBundle":false,"_integrity":"sha512-FouTTcLdT++gwgKVnBN8CEVeFvY/OKzeaoH/L9LBvZhbjUotLthFWAdKa8WeOMt5x7Rs7uvBpu7IdcrtRD3wBA==","_location":"/@octokit/rest","_phantomChildren":{"os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.28.8","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.28.8","saveSpec":null,"fetchSpec":"16.28.8"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.28.8.tgz","_spec":"16.28.8","_where":"/Users/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/request":"^5.0.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^3.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/fixtures-server":"^5.0.1","@octokit/routes":"20.9.2","@types/node":"^12.0.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.0.0","coveralls":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^2.1.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^3.0.0","nock":"^10.0.0","npm-run-all":"^4.1.2","nyc":"^14.0.0","prettier":"^1.14.2","proxy":"^0.2.4","semantic-release":"^15.0.0","sinon":"^7.2.4","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","standard":"^14.0.2","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"node scripts/generate-types","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","generate-routes":"node scripts/generate-routes","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"standard","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","test:memory":"mocha test/memory-test","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect","cy"],"ignore":["/docs"]},"types":"index.d.ts","version":"16.28.8"}; /***/ }), @@ -3796,7 +3796,7 @@ function octokitRestNormalizeGitReferenceResponses (octokit) { /***/ 314: /***/ (function(module) { -module.exports = {"_args":[["@octokit/graphql@2.1.3","/home/victor/Documents/Apps/create-release"]],"_from":"@octokit/graphql@2.1.3","_id":"@octokit/graphql@2.1.3","_inBundle":false,"_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_location":"/@octokit/graphql","_phantomChildren":{},"_requested":{"type":"version","registry":true,"raw":"@octokit/graphql@2.1.3","name":"@octokit/graphql","escapedName":"@octokit%2fgraphql","scope":"@octokit","rawSpec":"2.1.3","saveSpec":null,"fetchSpec":"2.1.3"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_spec":"2.1.3","_where":"/home/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"description":"GitHub GraphQL API client for browsers and Node","devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"files":["lib"],"homepage":"https://github.com/octokit/graphql.js#readme","keywords":["octokit","github","api","graphql"],"license":"MIT","main":"index.js","name":"@octokit/graphql","publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/graphql.js.git"},"scripts":{"build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","prebuild":"mkdirp dist/","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"version":"2.1.3"}; +module.exports = {"_args":[["@octokit/graphql@2.1.3","/Users/victor/Documents/Apps/create-release"]],"_from":"@octokit/graphql@2.1.3","_id":"@octokit/graphql@2.1.3","_inBundle":false,"_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_location":"/@octokit/graphql","_phantomChildren":{},"_requested":{"type":"version","registry":true,"raw":"@octokit/graphql@2.1.3","name":"@octokit/graphql","escapedName":"@octokit%2fgraphql","scope":"@octokit","rawSpec":"2.1.3","saveSpec":null,"fetchSpec":"2.1.3"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_spec":"2.1.3","_where":"/Users/victor/Documents/Apps/create-release","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"description":"GitHub GraphQL API client for browsers and Node","devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"files":["lib"],"homepage":"https://github.com/octokit/graphql.js#readme","keywords":["octokit","github","api","graphql"],"license":"MIT","main":"index.js","name":"@octokit/graphql","publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/graphql.js.git"},"scripts":{"build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","prebuild":"mkdirp dist/","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"version":"2.1.3"}; /***/ }), @@ -7865,6 +7865,8 @@ async function run() { const draft = core.getInput('draft', { required: false }) === 'true'; const prerelease = core.getInput('prerelease', { required: false }) === 'true'; + let responseData = null; + if (replaceOldTag) { // Check to see if we need to replace an older release @@ -7877,19 +7879,22 @@ async function run() { repo, ref: `tags/${tag}` }); - const refSha = getRefResponse.data.object.sha; - if (refSha !== process.env.GITHUB_SHA) { - // Delete the tag and release associated with this release - // Get a release by tag name - // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name - // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag - const getReleaseResponse = await github.repos.getReleaseByTag({ - owner, - repo, - tag - }); + // Get a release by tag name + // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag + const getReleaseResponse = await github.repos.getReleaseByTag({ + owner, + repo, + tag + }); + + if (refSha === process.env.GITHUB_SHA) { + // We don't need to bother with creating a release because it's already created + responseData = getReleaseResponse; + } else { + // Delete the tag and release associated with this release const releaseId = getReleaseResponse.data.id; @@ -7921,22 +7926,24 @@ async function run() { } } - // Create a release - // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release - // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release - const createReleaseResponse = await github.repos.createRelease({ - owner, - repo, - tag_name: tag, - name: releaseName, - draft, - prerelease - }); + if (!responseData) { + // Create a release + // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release + responseData = await github.repos.createRelease({ + owner, + repo, + tag_name: tag, + name: releaseName, + draft, + prerelease + }); + } // Get the ID, html_url, and upload URL for the created Release from the response const { data: { id: releaseId, html_url: htmlUrl, upload_url: uploadUrl } - } = createReleaseResponse; + } = responseData; // Set the output variables for use by other actions: https://github.com/actions/toolkit/tree/master/packages/core#inputsoutputs core.setOutput('id', releaseId); diff --git a/src/create-release.js b/src/create-release.js index 7792da6e..c30978ca 100644 --- a/src/create-release.js +++ b/src/create-release.js @@ -19,6 +19,8 @@ async function run() { const draft = core.getInput('draft', { required: false }) === 'true'; const prerelease = core.getInput('prerelease', { required: false }) === 'true'; + let responseData = null; + if (replaceOldTag) { // Check to see if we need to replace an older release @@ -31,19 +33,22 @@ async function run() { repo, ref: `tags/${tag}` }); - const refSha = getRefResponse.data.object.sha; - if (refSha !== process.env.GITHUB_SHA) { - // Delete the tag and release associated with this release - // Get a release by tag name - // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name - // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag - const getReleaseResponse = await github.repos.getReleaseByTag({ - owner, - repo, - tag - }); + // Get a release by tag name + // API Documentation: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-get-release-by-tag + const getReleaseResponse = await github.repos.getReleaseByTag({ + owner, + repo, + tag + }); + + if (refSha === process.env.GITHUB_SHA) { + // We don't need to bother with creating a release because it's already created + responseData = getReleaseResponse; + } else { + // Delete the tag and release associated with this release const releaseId = getReleaseResponse.data.id; @@ -75,22 +80,24 @@ async function run() { } } - // Create a release - // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release - // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release - const createReleaseResponse = await github.repos.createRelease({ - owner, - repo, - tag_name: tag, - name: releaseName, - draft, - prerelease - }); + if (!responseData) { + // Create a release + // API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release + // Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release + responseData = await github.repos.createRelease({ + owner, + repo, + tag_name: tag, + name: releaseName, + draft, + prerelease + }); + } // Get the ID, html_url, and upload URL for the created Release from the response const { data: { id: releaseId, html_url: htmlUrl, upload_url: uploadUrl } - } = createReleaseResponse; + } = responseData; // Set the output variables for use by other actions: https://github.com/actions/toolkit/tree/master/packages/core#inputsoutputs core.setOutput('id', releaseId); diff --git a/tests/create-release.test.js b/tests/create-release.test.js index 8061e699..c1c3b68b 100644 --- a/tests/create-release.test.js +++ b/tests/create-release.test.js @@ -52,7 +52,9 @@ describe('Create Release', () => { getReleaseByTag = jest.fn().mockReturnValueOnce({ data: { - id: 'releaseId' + id: 'releaseId', + html_url: 'htmlUrl', + upload_url: 'uploadUrl' } }); @@ -177,6 +179,8 @@ describe('Create Release', () => { .mockReturnValueOnce('false') .mockReturnValueOnce('false'); + core.setOutput = jest.fn(); + await run(); expect(getRef).toHaveBeenCalledWith({ @@ -185,16 +189,13 @@ describe('Create Release', () => { ref: 'tags/existing' }); - expect(getReleaseByTag).toHaveBeenCalledTimes(0); + expect(deleteRelease).toHaveBeenCalledTimes(0); - expect(createRelease).toHaveBeenCalledWith({ - owner: 'owner', - repo: 'repo', - tag_name: 'existing', - name: 'myRelease', - draft: false, - prerelease: false - }); + expect(createRelease).toHaveBeenCalledTimes(0); + + expect(core.setOutput).toHaveBeenNthCalledWith(1, 'id', 'releaseId'); + expect(core.setOutput).toHaveBeenNthCalledWith(2, 'html_url', 'htmlUrl'); + expect(core.setOutput).toHaveBeenNthCalledWith(3, 'upload_url', 'uploadUrl'); }); test('Older release is deleted', async () => {