Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log website URL upon deployment #1329

Merged
merged 12 commits into from
Aug 27, 2020
43 changes: 43 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions packages/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,7 @@ program
const rootFolder = path.resolve(process.cwd());
const outputRoot = path.join(rootFolder, '_site');
new Site(rootFolder, outputRoot, undefined, undefined, options.siteConfig).deploy(options.travis)
.then(() => {
logger.info('Deployed!');
})
.then(depUrl => (depUrl !== null ? logger.info(`Deployed at ${depUrl}!`) : logger.info('Deployed!')))
.catch(handleError);
printHeader();
});
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"nunjucks": "^3.2.0",
"path-is-inside": "^1.0.2",
"progress": "^2.0.3",
"simple-git": "^2.17.0",
"walk-sync": "^2.0.2",
"winston": "^2.4.4"
},
Expand Down
64 changes: 62 additions & 2 deletions packages/core/src/Site/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const path = require('path');
const Promise = require('bluebird');
const ProgressBar = require('progress');
const walkSync = require('walk-sync');
const simpleGit = require('simple-git');

const SiteConfig = require('./SiteConfig');
const Page = require('../Page');
Expand All @@ -18,6 +19,7 @@ const FsUtil = require('../utils/fsUtil');
const delay = require('../utils/delay');
const logger = require('../utils/logger');
const utils = require('../utils');
const gitUtil = require('../utils/git');

const {
LAYOUT_DEFAULT_NAME,
Expand Down Expand Up @@ -1249,6 +1251,7 @@ class Site {
branch: 'gh-pages',
message: 'Site Update.',
repo: '',
remote: 'origin',
};
process.env.NODE_DEBUG = 'gh-pages';
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -1298,13 +1301,70 @@ class Site {
};
}

return publish(basePath, options);
publish(basePath, options);
return options;
})
.then(resolve)
.then((options) => {
const git = simpleGit({ baseDir: process.cwd() });
options.remote = defaultDeployConfig.remote;
return Site.getDeploymentUrl(git, options);
})
.then(depUrl => resolve(depUrl))
.catch(reject);
});
}

/**
* Gets the deployed website's url, returning null if there was an error retrieving it.
*/
static getDeploymentUrl(git, options) {
const HTTPS_PREAMBLE = 'https://';
const SSH_PREAMBLE = 'git@github.com:';
const GITHUB_IO_PART = 'github.io';

// https://<name|org name>.github.io/<repo name>/
function constructGhPagesUrl(remoteUrl) {
if (!remoteUrl) {
return null;
}
if (remoteUrl.startsWith(HTTPS_PREAMBLE)) {
// https://github.com/<name|org>/<repo>.git (HTTPS)
const parts = remoteUrl.split('/');
const repoName = parts[parts.length - 1].toLowerCase();
const name = parts[parts.length - 2].toLowerCase();
return `https://${name}.${GITHUB_IO_PART}/${repoName}`;
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const parts = remoteUrl.split('/');
const repoName = parts[parts.length - 1].toLowerCase();
const name = parts[0].substring(SSH_PREAMBLE.length);
return `https://${name}.${GITHUB_IO_PART}/${repoName}`;
}
return null;
}

const { remote, branch, repo } = options;
const cnamePromise = gitUtil.getRemoteBranchFile(git, 'blob', remote, branch, 'CNAME');
const remoteUrlPromise = gitUtil.getRemoteUrl(git, remote);
const promises = [cnamePromise, remoteUrlPromise];

return Promise.all(promises)
.then((results) => {
const cname = results[0].trim();
const remoteUrl = results[1].trim();
if (cname) {
return cname;
} else if (repo) {
return constructGhPagesUrl(repo);
}
return constructGhPagesUrl(remoteUrl);
})
.catch((err) => {
logger.error(err);
return null;
});
}

_setTimestampVariable() {
const options = {
weekday: 'short',
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/utils/git.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Contains methods using simple-git to perform commands relating to git.
*/
module.exports = {
/**
* Returns the contents of a remote file, undefined if an error was encountered.
* See: https://git-scm.com/docs/git-cat-file for accepted values for each input.
*/
async getRemoteBranchFile(simpleGit, type, remote, branch, fileName) {
try {
const catFileTarget = `${remote}/${branch}:${fileName}`;
return await simpleGit.catFile([type, catFileTarget]);
} catch (e) {
return undefined;
}
},
/**
* Returns the contents of a remote url (https or ssh), undefined if an error was encountered.
*/
async getRemoteUrl(simpleGit, remote) {
try {
return await simpleGit.remote(['get-url', remote]);
} catch (e) {
return undefined;
}
},
};
22 changes: 20 additions & 2 deletions packages/core/test/unit/Site.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ jest.mock('fs');
jest.mock('walk-sync');
jest.mock('gh-pages');
jest.mock('../../src/Page');
jest.mock('simple-git', () => () => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this mock still necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ang-zeyu otherwise, there would be tons of warnings warn: message=fatal: Not a valid object name origin/gh-pages:CNAME thrown in the test for deployment in Site.test.js.

...jest.requireActual('simple-git')(),
// A test file should reduce dependencies on external libraries; use pure js functions instead.
// eslint-disable-next-line lodash/prefer-constant
catFile: jest.fn(() => 'mock-test-website.com'),
// eslint-disable-next-line lodash/prefer-constant
remote: jest.fn(() => 'https://github.com/mockName/mockRepo.git'),
}));

afterEach(() => fs.vol.reset());

Expand Down Expand Up @@ -470,7 +478,12 @@ test('Site deploys with default settings', async () => {
await site.deploy();
expect(ghpages.dir).toEqual('_site');
expect(ghpages.options)
.toEqual({ branch: 'gh-pages', message: 'Site Update.', repo: '' });
.toEqual({
branch: 'gh-pages',
message: 'Site Update.',
repo: '',
remote: 'origin',
});
});

test('Site deploys with custom settings', async () => {
Expand All @@ -490,7 +503,12 @@ test('Site deploys with custom settings', async () => {
await site.deploy();
expect(ghpages.dir).toEqual('_site');
expect(ghpages.options)
.toEqual({ branch: 'master', message: 'Custom Site Update.', repo: 'https://github.com/USER/REPO.git' });
.toEqual({
branch: 'master',
message: 'Custom Site Update.',
repo: 'https://github.com/USER/REPO.git',
remote: 'origin',
});
});

test('Site should not deploy without a built site', async () => {
Expand Down