2020-07-23 13:40:48 +00:00
|
|
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
const gulp = require('gulp');
|
2020-07-24 06:57:36 +00:00
|
|
|
const inquirer = require('inquirer');
|
2020-07-23 13:40:48 +00:00
|
|
|
const DevConfig = require('./dev-config');
|
|
|
|
const Git = require('./git');
|
|
|
|
const Jira = require('./jira');
|
|
|
|
const Utils = require('./utils');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Task to push a git branch and update tracker issue.
|
|
|
|
*/
|
|
|
|
class PushTask {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run the task.
|
|
|
|
*
|
|
|
|
* @param args Command line arguments.
|
|
|
|
* @param done Function to call when done.
|
|
|
|
*/
|
|
|
|
async run(args, done) {
|
|
|
|
try {
|
|
|
|
const remote = args.remote || DevConfig.get('upstreamRemote', 'origin');
|
|
|
|
let branch = args.branch;
|
|
|
|
const force = !!args.force;
|
|
|
|
|
|
|
|
if (!branch) {
|
|
|
|
branch = await Git.getCurrentBranch();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!branch) {
|
|
|
|
throw new Error('Cannot determine the current branch. Please make sure youu aren\'t in detached HEAD state');
|
|
|
|
} else if (branch == 'HEAD') {
|
|
|
|
throw new Error('Cannot push HEAD branch');
|
|
|
|
}
|
|
|
|
|
2020-07-24 06:57:36 +00:00
|
|
|
const keepRunning = await this.validateLastCommitMessage(branch);
|
|
|
|
|
|
|
|
if (!keepRunning) {
|
|
|
|
// Last commit not valid, stop.
|
|
|
|
console.log('Exiting...');
|
|
|
|
done();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-23 13:40:48 +00:00
|
|
|
// Push the branch.
|
|
|
|
console.log(`Pushing branch ${branch} to remote ${remote}...`);
|
|
|
|
await Git.push(remote, branch, force);
|
|
|
|
|
|
|
|
// Update tracker info.
|
|
|
|
console.log(`Branch pushed, update tracker info...`);
|
|
|
|
await this.updateTrackerGitInfo(branch, remote);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update git info in the tracker issue.
|
|
|
|
*
|
|
|
|
* @param branch Branch name.
|
|
|
|
* @param remote Remote used.
|
|
|
|
* @return Promise resolved when done.
|
|
|
|
*/
|
|
|
|
async updateTrackerGitInfo(branch, remote) {
|
|
|
|
// Parse the branch to get the project and issue number.
|
|
|
|
const branchData = Utils.parseBranch(branch);
|
|
|
|
|
|
|
|
// Get the repository data for the project.
|
|
|
|
let repositoryUrl = DevConfig.get(branchData.project + '.repositoryUrl');
|
|
|
|
let diffUrlTemplate = DevConfig.get(branchData.project + '.diffUrlTemplate', '');
|
|
|
|
let remoteUrl;
|
|
|
|
|
|
|
|
if (!repositoryUrl) {
|
|
|
|
// Calculate the repositoryUrl based on the remote URL.
|
|
|
|
remoteUrl = await Git.getRemoteUrl(remote);
|
|
|
|
|
|
|
|
repositoryUrl = remoteUrl.replace(/^https?:\/\//, 'git://');
|
|
|
|
if (!repositoryUrl.match(/\.git$/)) {
|
|
|
|
repositoryUrl += '.git';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!diffUrlTemplate) {
|
|
|
|
// Calculate the diffUrlTemplate based on the remote URL.
|
|
|
|
if (!remoteUrl) {
|
|
|
|
remoteUrl = await Git.getRemoteUrl(remoteUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
diffUrlTemplate = remoteUrl + '/compare/%headcommit%...%branch%';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search HEAD commit to put in the diff URL.
|
|
|
|
console.log ('Searching for head commit...');
|
|
|
|
let headCommit = await Git.getHeadCommit(branch, branchData);
|
|
|
|
|
|
|
|
if (!headCommit) {
|
|
|
|
throw new Error('Head commit not resolved, aborting update of tracker fields');
|
|
|
|
}
|
|
|
|
|
|
|
|
headCommit = headCommit.substr(0, 10);
|
|
|
|
console.log(`Head commit resolved to ${headCommit}`);
|
|
|
|
|
|
|
|
// Calculate last properties needed.
|
|
|
|
const diffUrl = diffUrlTemplate.replace('%branch%', branch).replace('%headcommit%', headCommit);
|
|
|
|
const fieldRepositoryUrl = DevConfig.get('tracker.fieldnames.repositoryurl', 'Pull from Repository');
|
|
|
|
const fieldBranch = DevConfig.get('tracker.fieldnames.branch', 'Pull Master Branch');
|
|
|
|
const fieldDiffUrl = DevConfig.get('tracker.fieldnames.diffurl', 'Pull Master Diff URL');
|
|
|
|
|
|
|
|
// Update tracker fields.
|
|
|
|
const updates = {};
|
|
|
|
updates[fieldRepositoryUrl] = repositoryUrl;
|
|
|
|
updates[fieldBranch] = branch;
|
|
|
|
updates[fieldDiffUrl] = diffUrl;
|
|
|
|
|
|
|
|
console.log('Setting tracker fields...');
|
|
|
|
await Jira.setCustomFields(branchData.issue, updates);
|
|
|
|
}
|
2020-07-24 06:57:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate last commit message comparing it with the branch name.
|
|
|
|
*
|
|
|
|
* @param branch Branch name.
|
|
|
|
* @return True if value is ok or the user wants to continue anyway, false to stop.
|
|
|
|
*/
|
|
|
|
async validateLastCommitMessage(branch) {
|
|
|
|
const branchData = Utils.parseBranch(branch);
|
|
|
|
|
|
|
|
const messages = await Git.messages(1);
|
|
|
|
const message = messages[0];
|
|
|
|
|
|
|
|
const issue = Utils.getIssueFromCommitMessage(message);
|
|
|
|
|
|
|
|
if (!issue || issue != branchData.issue) {
|
|
|
|
if (!issue) {
|
|
|
|
console.log('The issue number could not be found in the commit message.');
|
|
|
|
console.log(`Commit: ${message}`);
|
|
|
|
} else if (issue != branchData.issue) {
|
|
|
|
console.log('The issue number in the last commit does not match the branch being pushed to.');
|
|
|
|
console.log(`Branch: ${branchData.issue} vs. commit: ${issue}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const answer = await inquirer.prompt([
|
|
|
|
{
|
|
|
|
type: 'input',
|
|
|
|
name: 'confirm',
|
|
|
|
message: 'Are you sure you want to continue?',
|
|
|
|
default: 'n',
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
return answer.confirm == 'y';
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2020-07-23 13:40:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = PushTask;
|