diff --git a/CHANGELOG.md b/CHANGELOG.md index 2693c9c..57e60fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.0.0-beta.1 +## Deploy to root on `master` branch + +- when branch is `master`, the directory won't be deployed to `/branch/${branchName}`, but `/` instead, allowing consumers to only rely on this package and not need `gh-pages` in addition +- default `branch` value of `master` is added + # v0.2.8 ## Fix deployment id error diff --git a/README.md b/README.md index 61577de..0108b0b 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,10 @@ [![CircleCI](https://img.shields.io/circleci/project/github/oliverviljamaa/deploy-directory-on-branch-to-gh-pages/beta.svg)](https://circleci.com/gh/oliverviljamaa/deploy-directory-on-branch-to-gh-pages) [![npm](https://img.shields.io/npm/l/deploy-directory-on-branch-to-gh-pages.svg)](https://github.com/oliverviljamaa/deploy-directory-on-branch-to-gh-pages/blob/beta/LICENSE) -A Node and CLI tool that makes deploying a directory on a branch to GitHub pages easy and automatic, -to help your peers QA your built docs/demos easily for better feedback. +A Node and CLI tool that makes deploying to GitHub pages **by branch** easy and automatic, best used as part of a CI process. + +On `master`, your directory will be deployed to your GitHub page root similarly to other libraries, such as the wonderful [`gh-pages`](https://www.npmjs.com/package/gh-pages). +On other branches, it'll be deployed under `/branch/${branchName}`, allowing your peers to QA your built docs/demos easily for better feedback. It also sends a status to a Pull request, if one exists: @@ -42,7 +44,7 @@ deploy(options).catch(err => { console.log(err); }) | `token` | -t | [GitHub token](https://github.com/settings/tokens) | | `GITHUB_TOKEN` | * | * | | `owner` | -o | GitHub repo owner/org | | | * | | | `repo` | -r | GitHub repo name | | | * | | -| `branch` | -b | branch name | | | * | | +| `branch` | -b | branch name | `'master'` | | * | | | `buildUrl` | -u | link displayed when deployment fails | | | | | Therefore, if ran from CircleCI with a `GITHUB_TOKEN` environment variable present and the directory to be deployed is named `public`, _no configuration options are needed_, so just the following is enough: diff --git a/lib/deployment/preparation/preparation.js b/lib/deployment/preparation/preparation.js index 831301e..3701ce9 100644 --- a/lib/deployment/preparation/preparation.js +++ b/lib/deployment/preparation/preparation.js @@ -1,50 +1,39 @@ const shell = require('shelljs'); const path = require('path'); -const DEPLOY_BRANCH_DIRECTORY = 'branch'; +const BRANCH_DIRECTORY_NAME = 'branch'; shell.set('-e'); module.exports = { prepareDeployDirectory }; -function prepareDeployDirectory(directory, options) { - checkoutPagesBranchToDeployDirectory(directory); - moveDirectoryContentToDeployDirectory(directory, options); -} - -function checkoutPagesBranchToDeployDirectory(directory) { - createDeployDirectoryIfDoesNotExist(directory); +function prepareDeployDirectory(deployDirectory, { directory: sourceDirectory, branch }) { + createBranchDirectoryIfNeeded(deployDirectory, branch); - try { - pullGithubPagesBranchToDirectory(directory); - } catch (err) { - console.error(err); - console.log('gh-pages branch does not exist yet, it will be created automatically...'); - } + copyContentWithReplacement(sourceDirectory, getTargetDirectory(deployDirectory, branch)); } -function createDeployDirectoryIfDoesNotExist(directory) { - shell.mkdir('-p', directory); +function createBranchDirectoryIfNeeded(deployDirectory, branch) { + if (!isMaster(branch)) { + shell.mkdir('-p', getBranchDirectory(deployDirectory)); + } } -function pullGithubPagesBranchToDirectory(directory) { - shell.exec(`git --work-tree=./${directory} checkout gh-pages -- .`, { silent: true }); +function isMaster(branch) { + return branch === 'master'; } -function moveDirectoryContentToDeployDirectory(directory, options) { - createBranchDirectoryIfDoesNotExist(directory); - - const source = options.directory; - const target = path.join(directory, DEPLOY_BRANCH_DIRECTORY, options.branch); - - moveContent(source, target); +function getBranchDirectory(deployDirectory) { + return path.join(deployDirectory, BRANCH_DIRECTORY_NAME); } -function createBranchDirectoryIfDoesNotExist(directory) { - shell.mkdir('-p', path.join(directory, DEPLOY_BRANCH_DIRECTORY)); +function getTargetDirectory(deployDirectory, branch) { + return isMaster(branch) + ? deployDirectory + : path.join(getBranchDirectory(deployDirectory), branch); } -function moveContent(source, target) { +function copyContentWithReplacement(source, target) { shell.rm('-rf', target); shell.cp('-r', source, target); } diff --git a/lib/deployment/preparation/preparation.spec.js b/lib/deployment/preparation/preparation.spec.js index 66d51bc..328a482 100644 --- a/lib/deployment/preparation/preparation.spec.js +++ b/lib/deployment/preparation/preparation.spec.js @@ -14,58 +14,53 @@ const { prepareDeployDirectory } = require('./'); describe('Preparation', () => { afterEach(jest.resetAllMocks); - it('sets shell to throw error when an operation fails', () => { - expect(shell.set).toBeCalledWith('-e'); + describe('always', () => { + it('sets shell to throw error when an operation fails', () => { + expect(shell.set).toBeCalledWith('-e'); + }); }); - it('creates deploy directory if it does not exist', () => { - expect(shell.mkdir).not.toBeCalled(); - prepareDeployDirectory('a-directory', {}); - expect(shell.mkdir).toBeCalledWith('-p', 'a-directory'); - }); + describe('on master branch', () => { + const options = { directory: 'source', branch: 'master' }; - it('pulls gh-pages branch content to deploy directory', () => { - expect(shell.exec).not.toBeCalled(); - prepareDeployDirectory('a-directory', {}); - expect(shell.exec).toBeCalledWith(`git --work-tree=./a-directory checkout gh-pages -- .`, { - silent: true, + it('does not create branch directory', () => { + expect(shell.mkdir).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.mkdir).not.toBeCalled(); }); - }); - it('logs a message if pulling gh-pages branch content to deploy directory fails', () => { - console.log = jest.fn(); - - shell.exec.mockImplementation(() => { - throw new Error('An error'); + it('removes deploy directory to allow copying with replacement', () => { + expect(shell.rm).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.rm).toBeCalledWith('-rf', 'deploy-directory'); }); - expect(console.log).not.toBeCalled(); - prepareDeployDirectory('a-directory', {}); - expect(console.log).toBeCalled(); + it('moves content from source directory to deploy directory', () => { + expect(shell.cp).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.cp).toBeCalledWith('-r', 'source', 'deploy-directory'); + }); }); - it('creates branch directory if it does not exist', () => { - expect(shell.mkdir).not.toBeCalled(); - prepareDeployDirectory('a-directory', {}); - expect(shell.mkdir).toBeCalledWith('-p', 'a-directory/branch'); - }); + describe('on a non-master branch', () => { + const options = { directory: 'source', branch: 'not-master' }; - it('removes branch directory to be certain it is clean', () => { - expect(shell.rm).not.toBeCalled(); - prepareDeployDirectory('a-directory', { branch: 'a-branch' }); - expect(shell.rm).toBeCalledWith('-rf', 'a-directory/branch/a-branch'); - }); + it('creates branch directory ', () => { + expect(shell.mkdir).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.mkdir).toBeCalledWith('-p', 'deploy-directory/branch'); + }); + + it('removes current branch directory to allow copying with replacement', () => { + expect(shell.rm).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.rm).toBeCalledWith('-rf', 'deploy-directory/branch/not-master'); + }); - it('moves content from directory to be deployed to branch directory', () => { - expect(shell.cp).not.toBeCalled(); - prepareDeployDirectory('a-directory', { - directory: 'a-directory-to-be-deployed', - branch: 'a-branch', + it('moves content from source directory to branch directory', () => { + expect(shell.cp).not.toBeCalled(); + prepareDeployDirectory('deploy-directory', options); + expect(shell.cp).toBeCalledWith('-r', 'source', 'deploy-directory/branch/not-master'); }); - expect(shell.cp).toBeCalledWith( - '-r', - 'a-directory-to-be-deployed', - 'a-directory/branch/a-branch', - ); }); }); diff --git a/lib/options/options.js b/lib/options/options.js index 78bebd7..2a55145 100644 --- a/lib/options/options.js +++ b/lib/options/options.js @@ -9,13 +9,13 @@ function createOptions(passedOptions) { } function extendPassedOptions(options) { - return extendWithCircleVariablesIfCircle( - extendWithGithubTokenVariable(extendWithDefaultOptions(options)), + return extendWithDefaultOptions( + extendWithGithubTokenVariable(extendWithCircleVariablesIfCircle(options)), ); } function extendWithDefaultOptions(options) { - return { directory: 'public', ...options }; + return { directory: 'public', branch: 'master', ...options }; } function extendWithGithubTokenVariable(options) { diff --git a/lib/options/options.spec.js b/lib/options/options.spec.js index a0f6e58..5ae50cf 100644 --- a/lib/options/options.spec.js +++ b/lib/options/options.spec.js @@ -3,14 +3,24 @@ const { createOptions } = require('./'); describe('Options', () => { beforeEach(cleanEnvironmentVariables); - it('extends passed options with default directory to deploy', () => { + it('extends passed options with default directory to deploy and master branch', () => { + const options = { + token: 'a-token', + owner: 'an-owner', + repo: 'a-repo', + }; + expect(createOptions(options)).toEqual({ ...options, directory: 'public', branch: 'master' }); + }); + + it('prefers passed options to default options', () => { const options = { token: 'a-token', owner: 'an-owner', repo: 'a-repo', branch: 'a-branch', + directory: 'a-directory', }; - expect(createOptions(options)).toEqual({ ...options, directory: 'public' }); + expect(createOptions(options)).toEqual(options); }); it('extends passed options with github token variable if exists', () => { @@ -45,14 +55,13 @@ describe('Options', () => { }); it('throws if any required option is missing', () => { - expect.assertions(4); + expect.assertions(3); - const requiredOptions = ['token', 'owner', 'repo', 'branch']; + const requiredOptions = ['token', 'owner', 'repo']; const fullOptions = () => ({ token: 'a-token', owner: 'an-owner', repo: 'a-repo', - branch: 'a-branch', }); requiredOptions.forEach(name => { diff --git a/package.json b/package.json index 174473a..8fc898a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deploy-directory-on-branch-to-gh-pages", - "version": "0.2.8", + "version": "1.0.0-beta.1", "description": "A Node library that makes deploying a directory on a branch to GitHub pages easy and automatic.", "bin": { "deploy-directory-on-branch-to-gh-pages": "bin/deploy-directory-on-branch-to-gh-pages.js"