diff --git a/.gitignore b/.gitignore index c3ad11e..5fe23e9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ projectFilesBackup .DS_Store dist/ + +config.json +changelog.md +changelog.md.bk diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..7a850f1 --- /dev/null +++ b/config.example.json @@ -0,0 +1,6 @@ +{ + "github": { + "username": "", + "token": "" + } +} diff --git a/gulpfile.js b/gulpfile.js index f9fb173..5daae14 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -78,3 +78,122 @@ const dev = series(build, serve, watcher); exports.build = build; exports.zip = series(build, zipper); exports.default = dev; + +// release imports +const path = require('path'); +const releaseUtils = require('@tryghost/release-utils'); + +let config; +try { + config = require('./config'); +} catch (err) { + config = null; +} + +const REPO = 'TryGhost/Casper'; +const USER_AGENT = 'Casper'; +const CHANGELOG_PATH = path.join(process.cwd(), '.', 'changelog.md'); + +const changelog = ({previousVersion}) => { + const changelog = new releaseUtils.Changelog({ + changelogPath: CHANGELOG_PATH, + folder: path.join(process.cwd(), '.') + }); + + changelog + .write({ + githubRepoPath: `https://github.com/${REPO}`, + lastVersion: previousVersion + }) + .sort() + .clean(); +}; + +const previousRelease = () => { + return releaseUtils + .releases + .get({ + userAgent: USER_AGENT, + uri: `https://api.github.com/repos/${REPO}/releases` + }) + .then((response) => { + if (!response || !response.length) { + console.log('No releases found. Skipping'); + return; + } + + console.log(`Previous version ${response[0].name}`); + return response[0].name; + }); +}; + +/** + * + * `yarn ship` will trigger `postship` task. + * + * [optional] For full automation + * + * `GHOST=2.10.1,2.10.0 yarn ship` + * First value: Ships with Ghost + * Second value: Compatible with Ghost/GScan + * + * You can manually run in case the task has thrown an error. + * + * `npm_package_version=0.5.0 gulp release` + */ +const release = () => { + // @NOTE: https://yarnpkg.com/lang/en/docs/cli/version/ + const newVersion = process.env.npm_package_version; + let shipsWithGhost = '{version}'; + let compatibleWithGhost = '2.10.0'; + const ghostEnvValues = process.env.GHOST || null; + + if (ghostEnvValues) { + shipsWithGhost = ghostEnvValues.split(',')[0]; + compatibleWithGhost = ghostEnvValues.split(',')[1]; + + if (!compatibleWithGhost) { + compatibleWithGhost = '2.10.0'; + } + } + + if (!newVersion || newVersion === '') { + console.log('Invalid version.'); + return; + } + + console.log(`\nDraft release for ${newVersion}.`); + + if (!config || !config.github || !config.github.username || !config.github.token) { + console.log('Please copy config.example.json and configure Github token.'); + return; + } + + return previousRelease() + .then((previousVersion)=> { + + changelog({previousVersion}); + + return releaseUtils + .releases + .create({ + draft: true, + preRelease: false, + tagName: newVersion, + releaseName: newVersion, + userAgent: USER_AGENT, + uri: `https://api.github.com/repos/${REPO}/releases`, + github: { + username: config.github.username, + token: config.github.token + }, + content: [`**Ships with Ghost ${shipsWithGhost} Compatible with Ghost >= ${compatibleWithGhost}**\n\n`], + changelogPath: CHANGELOG_PATH + }) + .then((response)=> { + console.log(`\nRelease draft generated: ${response.releaseUrl}\n`); + }); + }); +}; + +exports.release = release; diff --git a/package.json b/package.json index 2031311..51d4b8b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "test": "gscan .", "pretest": "gulp build", "preship": "yarn test", - "ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn version && git push --follow-tags; fi" + "ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn version && git push --follow-tags; else echo \"Uncomitted changes found.\" && exit 1; fi", + "postship": "git fetch && gulp release" }, "author": { "name": "Ghost Foundation", @@ -44,6 +45,7 @@ "bugs": "https://github.com/TryGhost/Casper/issues", "contributors": "https://github.com/TryGhost/Casper/graphs/contributors", "devDependencies": { + "@tryghost/release-utils": "0.2.0", "autoprefixer": "9.4.10", "beeper": "1.1.1", "cssnano": "4.1.10", diff --git a/yarn.lock b/yarn.lock index 64a664c..34e4afd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11,6 +11,17 @@ mkdirp "0.5.0" yauzl "2.4.1" +"@tryghost/release-utils@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@tryghost/release-utils/-/release-utils-0.2.0.tgz#acced7a5fabce8d868cbf582feb918b81a3f8abd" + dependencies: + bluebird "^3.5.3" + emoji-regex "^8.0.0" + execa "^1.0.0" + lodash "^4.17.11" + request "^2.88.0" + request-promise "^4.2.4" + "@types/q@^1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18" @@ -327,7 +338,7 @@ binary-extensions@^1.0.0: version "1.13.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.0.tgz#9523e001306a32444b907423f1de2164222f6ab1" -bluebird@^3.0.5, bluebird@^3.4.6: +bluebird@^3.0.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" @@ -763,6 +774,16 @@ cosmiconfig@^5.0.0: lodash.get "^4.4.2" parse-json "^4.0.0" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + css-color-function@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e" @@ -1071,6 +1092,10 @@ electron-to-chromium@^1.3.113: version "1.3.113" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -1177,6 +1202,18 @@ event-stream@3.3.4: stream-combiner "~0.0.4" through "~2.3.1" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1484,6 +1521,12 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -2070,6 +2113,10 @@ is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + is-svg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" @@ -2526,6 +2573,10 @@ next-tick@1: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + node-loggly-bulk@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/node-loggly-bulk/-/node-loggly-bulk-2.2.4.tgz#bdd8638d97c43ecf1e1831ca98b250968fa6dee9" @@ -2612,6 +2663,12 @@ npm-packlist@^1.1.6: ignore-walk "^3.0.1" npm-bundled "^1.0.1" +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -2761,6 +2818,10 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + parse-filepath@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" @@ -2812,6 +2873,10 @@ path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -3242,11 +3307,11 @@ pseudomap@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -psl@^1.1.24: +psl@^1.1.24, psl@^1.1.28: version "1.1.31" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" -pump@3.0.0: +pump@3.0.0, pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" dependencies: @@ -3272,7 +3337,7 @@ punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -3428,7 +3493,22 @@ replace-homedir@^1.0.0: is-absolute "^1.0.0" remove-trailing-separator "^1.1.0" -"request@>=2.76.0 <3.0.0": +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" + dependencies: + lodash "^4.17.11" + +request-promise@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.4.tgz#1c5ed0d71441e38ad58c7ce4ea4ea5b06d54b310" + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +"request@>=2.76.0 <3.0.0", request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" dependencies: @@ -3560,7 +3640,7 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0: +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -3621,6 +3701,16 @@ setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + sigmund@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -3763,6 +3853,10 @@ statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + stream-combiner@~0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" @@ -3828,6 +3922,10 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -3966,6 +4064,13 @@ to-through@^2.0.0: dependencies: through2 "^2.0.3" +tough-cookie@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -4206,7 +4311,7 @@ which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" -which@^1.2.14: +which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" dependencies: