Skip to content

Commit dce7709

Browse files
committed
feat(github): support usage of gh-token for deployment from external env
In order to being able to push to github from CI (Travis for example), we should be able to provide a token to the cli, as `--gh-token=XYZ`. This modification allow to use this token in the destination url. This also allow user to push to another github repository if it uses a different `--gh-username` from the one used for the checkout.
1 parent 142c518 commit dce7709

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

packages/angular-cli/commands/github-pages-deploy.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,13 @@ const githubPagesDeployCommand = Command.extend({
180180
.then(function(stdout) {
181181
if (!/origin\s+(https:\/\/|git@)github\.com/m.test(stdout)) {
182182
return createGithubRepoTask.run(createGithubRepoOptions)
183-
.then(() => {
183+
.then(() => generateRemoteUrl())
184+
.then((upstream: string) => {
184185
// only push starting branch if it's not the destinationBranch
185186
// this happens commonly when using github user pages, since
186187
// they require the destination branch to be 'master'
187188
if (destinationBranch !== initialBranch) {
188-
execPromise(`git push -u origin ${initialBranch}`);
189+
execPromise(`git push -u ${upstream} ${initialBranch}`);
189190
}
190191
});
191192
}
@@ -255,16 +256,17 @@ const githubPagesDeployCommand = Command.extend({
255256
}
256257

257258
function pushToGitRepo() {
258-
return execPromise(`git push origin ${ghPagesBranch}:${destinationBranch}`)
259+
return generateRemoteUrl()
260+
.then(upstream => {
261+
return execPromise(`git push ${upstream} ${ghPagesBranch}:${destinationBranch}`);
262+
})
259263
.catch((err) => returnStartingBranch()
260-
.catch(() => Promise.reject(err) ));
264+
.catch(() => Promise.reject(err) ));
261265
}
262266

263267
function printProjectUrl() {
264-
return execPromise('git remote -v')
265-
.then((stdout) => {
266-
let match = stdout.match(/origin\s+(?:https:\/\/|git@)github\.com(?:\:|\/)([^\/]+)/m);
267-
let userName = match[1].toLowerCase();
268+
return getUsernameFromGitOrigin()
269+
.then((userName) => {
268270
let url = `https://${userName}.github.io/${options.userPage ? '' : (baseHref + '/')}`;
269271
ui.writeLine(chalk.green(`Deployed! Visit ${url}`));
270272
ui.writeLine('Github pages might take a few minutes to show the deployed site.');
@@ -276,11 +278,37 @@ const githubPagesDeployCommand = Command.extend({
276278
ui.writeLine(error.message);
277279
let msg = 'There was a permissions error during git file operations, ' +
278280
'please close any open project files/folders and try again.';
281+
msg += `\nYou might also need to return to the ${initialBranch} branch manually.`;
279282
return Promise.reject(new SilentError(msg.concat(branchErrMsg)));
280283
} else {
281284
return Promise.reject(error);
282285
}
283286
}
287+
288+
function generateRemoteUrl(): Promise<String> {
289+
if (createGithubRepoOptions.ghToken && createGithubRepoOptions.ghUsername) {
290+
return Promise.resolve(`https://${createGithubRepoOptions.ghToken}@github.com/` +
291+
`${createGithubRepoOptions.ghUsername}/${createGithubRepoOptions.projectName}.git`);
292+
}
293+
294+
if (createGithubRepoOptions.ghToken && !createGithubRepoOptions.ghUsername) {
295+
return getUsernameFromGitOrigin()
296+
.then(username => {
297+
return Promise.resolve(`https://${createGithubRepoOptions.ghToken}@github.com/` +
298+
`${username}/${createGithubRepoOptions.projectName}.git`);
299+
});
300+
}
301+
302+
return Promise.resolve('origin');
303+
}
304+
305+
function getUsernameFromGitOrigin(): Promise<String> {
306+
return execPromise('git remote -v')
307+
.then((stdout) => {
308+
let match = stdout.match(/origin\s+(?:https:\/\/|git@)github\.com(?:\:|\/)([^\/]+)/m);
309+
return match[1].toLowerCase();
310+
});
311+
}
284312
}
285313
});
286314

tests/acceptance/github-pages-deploy.spec.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,44 @@ describe('Acceptance: ng github-pages:deploy', function() {
7777
return ng(['github-pages:deploy', '--skip-build']);
7878
});
7979

80+
it('should deploy with token and username', function () {
81+
let token = 'token',
82+
username = 'bar';
83+
84+
execStub.addExecSuccess('git status --porcelain')
85+
.addExecSuccess('git rev-parse --abbrev-ref HEAD', initialBranch)
86+
.addExecSuccess('git remote -v', remote)
87+
.addExecSuccess(`git checkout ${ghPagesBranch}`)
88+
.addExecSuccess('git ls-files')
89+
.addExecSuccess('git rm -r ')
90+
.addExecSuccess('git add .')
91+
.addExecSuccess(`git commit -m "${message}"`)
92+
.addExecSuccess(`git checkout ${initialBranch}`)
93+
.addExecSuccess(`git push https://${token}@github.com/${username}/${project}.git ${ghPagesBranch}:${ghPagesBranch}`)
94+
.addExecSuccess('git remote -v', remote);
95+
96+
return ng(['github-pages:deploy', '--skip-build', `--gh-token=${token}`, `--gh-username=${username}`]);
97+
})
98+
99+
it('should deploy with token only', function () {
100+
let token = 'token';
101+
102+
execStub.addExecSuccess('git status --porcelain')
103+
.addExecSuccess('git rev-parse --abbrev-ref HEAD', initialBranch)
104+
.addExecSuccess('git remote -v', remote)
105+
.addExecSuccess(`git checkout ${ghPagesBranch}`)
106+
.addExecSuccess('git ls-files')
107+
.addExecSuccess('git rm -r ')
108+
.addExecSuccess('git add .')
109+
.addExecSuccess(`git commit -m "${message}"`)
110+
.addExecSuccess(`git checkout ${initialBranch}`)
111+
.addExecSuccess('git remote -v', remote)
112+
.addExecSuccess(`git push https://${token}@github.com/username/${project}.git ${ghPagesBranch}:${ghPagesBranch}`)
113+
.addExecSuccess('git remote -v', remote);
114+
115+
return ng(['github-pages:deploy', '--skip-build', `--gh-token=${token}`]);
116+
});
117+
80118
it('should deploy with changed defaults', function() {
81119
let userPageBranch = 'master',
82120
message = 'not new gh-pages version';
@@ -126,14 +164,14 @@ describe('Acceptance: ng github-pages:deploy', function() {
126164
.addExecSuccess('git rev-parse --abbrev-ref HEAD', initialBranch)
127165
.addExecSuccess('git remote -v', noRemote)
128166
.addExecSuccess(`git remote add origin [email protected]:${username}/${project}.git`)
129-
.addExecSuccess(`git push -u origin ${initialBranch}`)
167+
.addExecSuccess(`git push -u https://${token}@github.com/${username}/${project}.git ${initialBranch}`)
130168
.addExecSuccess(`git checkout ${ghPagesBranch}`)
131169
.addExecSuccess('git ls-files')
132170
.addExecSuccess('git rm -r ')
133171
.addExecSuccess('git add .')
134172
.addExecSuccess(`git commit -m "${message}"`)
135173
.addExecSuccess(`git checkout ${initialBranch}`)
136-
.addExecSuccess(`git push origin ${ghPagesBranch}:${ghPagesBranch}`)
174+
.addExecSuccess(`git push https://${token}@github.com/${username}/${project}.git ${ghPagesBranch}:${ghPagesBranch}`)
137175
.addExecSuccess('git remote -v', remote);
138176

139177
var httpsStub = sinon.stub(https, 'request', httpsRequestStubFunc);

0 commit comments

Comments
 (0)