diff --git a/bin/gh-pages.js b/bin/gh-pages.js index 88c138db..bf51f2c4 100755 --- a/bin/gh-pages.js +++ b/bin/gh-pages.js @@ -51,6 +51,11 @@ function main(args) { .option('-g, --tag ', 'add tag to commit') .option('--git ', 'Path to git executable', ghpages.defaults.git) .option('-t, --dotfiles', 'Include dotfiles') + .option('--nojekyll', 'Add a .nojekyll file to disable Jekyll') + .option( + '--cname ', + 'Add a CNAME file with the name of your custom domain' + ) .option('-r, --repo ', 'URL of the repository you are pushing to') .option('-p, --depth ', 'depth for clone', ghpages.defaults.depth) .option( @@ -121,6 +126,7 @@ function main(args) { git: options.git, depth: options.depth, dotfiles: !!options.dotfiles, + nojekyll: !!options.nojekyll, add: !!options.add, remove: options.remove, remote: options.remote, diff --git a/lib/index.js b/lib/index.js index 42613de7..f74e6fd0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -184,6 +184,12 @@ exports.publish = function publish(basePath, config, callback) { }) .then((git) => { log('Copying files'); + if (options.nojekyll) { + fs.createFileSync(path.join(git.cwd, '.nojekyll')); + } + if (options.cname) { + fs.writeFileSync(path.join(git.cwd, 'CNAME'), options.cname); + } return copy(files, basePath, path.join(git.cwd, options.dest)).then( function () { return git; diff --git a/readme.md b/readme.md index be8cd9b2..2c739e78 100644 --- a/readme.md +++ b/readme.md @@ -128,6 +128,35 @@ Example use of the `dotfiles` option: ghpages.publish('dist', {dotfiles: true}, callback); ``` +#### options.nojekyll + * type: `boolean` + * default: `false` + +Write out a `.nojekyll` file to [bypass Jekyll on GitHub Pages](https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/). + +Example use of the `nojekyll` option: + +```js +/** + * The usage below will add a `.nojekyll` file to the output. + */ +ghpages.publish('dist', {nojekyll: true}, callback); +``` + +#### options.cname + * type: `string` + +Write out a `CNAME` file with a custom domain name. + +Example use of the `cname` option: + +```js +/** + * The usage below will add a `CNAME` file to the output. + */ +ghpages.publish('dist', {cname: 'custom-domain.com'}, callback); +``` + #### options.add * type: `boolean` @@ -402,10 +431,10 @@ If `gh-pages` fails, you may find that you need to manually clean up the cache d ### Deploying to github pages with custom domain -Modify the deployment line to your deploy script if you use custom domain. This will prevent the deployment from removing the domain settings in GitHub. +Use the `--cname` option to create a `CNAME` file with the name of your custom domain. See [the GitHub docs](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site) for more detail. ``` -echo your_cutom_domain.online > ./build/CNAME && gh-pages -d build" +gh-pages -d build --cname custom-domain.com" ``` ### Deploying with GitHub Actions diff --git a/test/bin/gh-pages.spec.js b/test/bin/gh-pages.spec.js index bc618424..e0353fca 100644 --- a/test/bin/gh-pages.spec.js +++ b/test/bin/gh-pages.spec.js @@ -42,6 +42,11 @@ describe('gh-pages', () => { dist: 'lib', config: {dotfiles: true}, }, + { + args: ['--dist', 'lib', '--nojekyll'], + dist: 'lib', + config: {nojekyll: true}, + }, { args: ['--dist', 'lib', '--dest', 'target'], dist: 'lib', diff --git a/test/integration/cname.spec.js b/test/integration/cname.spec.js new file mode 100644 index 00000000..1379f172 --- /dev/null +++ b/test/integration/cname.spec.js @@ -0,0 +1,38 @@ +const helper = require('../helper.js'); +const ghPages = require('../../lib/index.js'); +const path = require('path'); + +const fixtures = path.join(__dirname, 'fixtures'); +const fixtureName = 'cname'; + +beforeEach(() => { + ghPages.clean(); +}); + +describe('the --cname option', () => { + it('adds a CNAME file', (done) => { + const local = path.join(fixtures, fixtureName, 'local'); + const expected = path.join(fixtures, fixtureName, 'expected'); + const branch = 'gh-pages'; + + helper.setupRemote(fixtureName, {branch}).then((url) => { + const options = { + repo: url, + user: { + name: 'User Name', + email: 'user@email.com', + }, + cname: 'custom-domain.com', + }; + ghPages.publish(local, options, (err) => { + if (err) { + return done(err); + } + helper + .assertContentsMatch(expected, url, branch) + .then(() => done()) + .catch(done); + }); + }); + }); +}); diff --git a/test/integration/fixtures/cname/expected/CNAME b/test/integration/fixtures/cname/expected/CNAME new file mode 100644 index 00000000..4daa8b62 --- /dev/null +++ b/test/integration/fixtures/cname/expected/CNAME @@ -0,0 +1 @@ +custom-domain.com \ No newline at end of file diff --git a/test/integration/fixtures/cname/expected/hello-world.txt b/test/integration/fixtures/cname/expected/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/cname/expected/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/cname/local/hello-world.txt b/test/integration/fixtures/cname/local/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/cname/local/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/cname/remote/initial b/test/integration/fixtures/cname/remote/initial new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/fixtures/nojekyll-exists/expected/.nojekyll b/test/integration/fixtures/nojekyll-exists/expected/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/fixtures/nojekyll-exists/expected/hello-world.txt b/test/integration/fixtures/nojekyll-exists/expected/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/nojekyll-exists/expected/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/nojekyll-exists/local/hello-world.txt b/test/integration/fixtures/nojekyll-exists/local/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/nojekyll-exists/local/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/nojekyll-exists/remote/.nojekyll b/test/integration/fixtures/nojekyll-exists/remote/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/fixtures/nojekyll-exists/remote/initial b/test/integration/fixtures/nojekyll-exists/remote/initial new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/fixtures/nojekyll/expected/.nojekyll b/test/integration/fixtures/nojekyll/expected/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/fixtures/nojekyll/expected/hello-world.txt b/test/integration/fixtures/nojekyll/expected/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/nojekyll/expected/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/nojekyll/local/hello-world.txt b/test/integration/fixtures/nojekyll/local/hello-world.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/test/integration/fixtures/nojekyll/local/hello-world.txt @@ -0,0 +1 @@ +Hello World! diff --git a/test/integration/fixtures/nojekyll/remote/initial b/test/integration/fixtures/nojekyll/remote/initial new file mode 100644 index 00000000..e69de29b diff --git a/test/integration/nojekyll.spec.js b/test/integration/nojekyll.spec.js new file mode 100644 index 00000000..4fce8dfe --- /dev/null +++ b/test/integration/nojekyll.spec.js @@ -0,0 +1,38 @@ +const helper = require('../helper.js'); +const ghPages = require('../../lib/index.js'); +const path = require('path'); + +const fixtures = path.join(__dirname, 'fixtures'); +const fixtureName = 'nojekyll'; + +beforeEach(() => { + ghPages.clean(); +}); + +describe('the --nojekyll option', () => { + it('adds a .nojekyll file', (done) => { + const local = path.join(fixtures, fixtureName, 'local'); + const expected = path.join(fixtures, fixtureName, 'expected'); + const branch = 'gh-pages'; + + helper.setupRemote(fixtureName, {branch}).then((url) => { + const options = { + repo: url, + user: { + name: 'User Name', + email: 'user@email.com', + }, + nojekyll: true, + }; + ghPages.publish(local, options, (err) => { + if (err) { + return done(err); + } + helper + .assertContentsMatch(expected, url, branch) + .then(() => done()) + .catch(done); + }); + }); + }); +}); diff --git a/test/integration/nojekyllExists.spec.js b/test/integration/nojekyllExists.spec.js new file mode 100644 index 00000000..155239ae --- /dev/null +++ b/test/integration/nojekyllExists.spec.js @@ -0,0 +1,38 @@ +const helper = require('../helper.js'); +const ghPages = require('../../lib/index.js'); +const path = require('path'); + +const fixtures = path.join(__dirname, 'fixtures'); +const fixtureName = 'nojekyll-exists'; + +beforeEach(() => { + ghPages.clean(); +}); + +describe('the --nojekyll option', () => { + it('works even if the .nojekyll file already exists', (done) => { + const local = path.join(fixtures, fixtureName, 'local'); + const expected = path.join(fixtures, fixtureName, 'expected'); + const branch = 'gh-pages'; + + helper.setupRemote(fixtureName, {branch}).then((url) => { + const options = { + repo: url, + user: { + name: 'User Name', + email: 'user@email.com', + }, + nojekyll: true, + }; + ghPages.publish(local, options, (err) => { + if (err) { + return done(err); + } + helper + .assertContentsMatch(expected, url, branch) + .then(() => done()) + .catch(done); + }); + }); + }); +});