renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
152 lines • 6.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GerritScm = void 0;
exports.configureScm = configureScm;
const tslib_1 = require("tslib");
const crypto_1 = require("crypto");
const logger_1 = require("../../../logger");
const git = tslib_1.__importStar(require("../../../util/git"));
const hash_1 = require("../../../util/hash");
const default_scm_1 = require("../default-scm");
const client_1 = require("./client");
let repository;
let username;
function configureScm(repo, login) {
repository = repo;
username = login;
}
class GerritScm extends default_scm_1.DefaultGitScm {
async branchExists(branchName) {
const searchConfig = { state: 'open', branchName };
const change = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
if (change) {
return true;
}
return git.branchExists(branchName);
}
async getBranchCommit(branchName) {
const searchConfig = { state: 'open', branchName };
const change = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
if (change) {
return change.current_revision;
}
return git.getBranchCommit(branchName);
}
async isBranchBehindBase(branchName, baseBranch) {
const searchConfig = {
state: 'open',
branchName,
targetBranch: baseBranch,
};
const change = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
if (change) {
const currentGerritPatchset = change.revisions[change.current_revision];
return currentGerritPatchset.actions?.rebase.enabled === true;
}
return true;
}
async isBranchConflicted(baseBranch, branch) {
const searchConfig = {
state: 'open',
branchName: branch,
targetBranch: baseBranch,
};
const change = (await client_1.client.findChanges(repository, searchConfig)).pop();
if (change) {
const mergeInfo = await client_1.client.getMergeableInfo(change);
return !mergeInfo.mergeable;
}
else {
logger_1.logger.warn({ branch, baseBranch }, 'There is no open change with this branch');
return true;
}
}
async isBranchModified(branchName) {
const searchConfig = { state: 'open', branchName };
const change = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
if (change) {
const currentGerritPatchset = change.revisions[change.current_revision];
return currentGerritPatchset.uploader.username !== username;
}
return false;
}
async commitAndPush(commit) {
logger_1.logger.debug(`commitAndPush(${commit.branchName})`);
const searchConfig = {
state: 'open',
branchName: commit.branchName,
targetBranch: commit.baseBranch,
};
const existingChange = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
let hasChanges = true;
const message = typeof commit.message === 'string' ? [commit.message] : commit.message;
// In Gerrit, the change subject/title is the first line of the commit message
if (commit.prTitle) {
const firstMessageLines = message[0].split('\n');
firstMessageLines[0] = commit.prTitle;
message[0] = firstMessageLines.join('\n');
}
commit.message = [
...message,
`Renovate-Branch: ${commit.branchName}\nChange-Id: ${existingChange?.change_id ?? generateChangeId()}`,
];
const commitResult = await git.prepareCommit({ ...commit, force: true });
if (commitResult) {
const { commitSha } = commitResult;
if (existingChange?.revisions && existingChange.current_revision) {
const fetchRefSpec = existingChange.revisions[existingChange.current_revision].ref;
await git.fetchRevSpec(fetchRefSpec); //fetch current ChangeSet for git diff
hasChanges = await git.hasDiff('HEAD', 'FETCH_HEAD'); //avoid empty patchsets
}
if (hasChanges || commit.force) {
const pushResult = await git.pushCommit({
sourceRef: commit.branchName,
targetRef: `refs/for/${commit.baseBranch}%notify=NONE`,
files: commit.files,
});
if (pushResult) {
//existingChange was the old change before commit/push. we need to approve again, if it was previously approved from renovate
if (existingChange &&
client_1.client.wasApprovedBy(existingChange, username)) {
await client_1.client.approveChange(existingChange._number);
}
return commitSha;
}
}
}
return null; //empty commit, no changes in this Gerrit-Change
}
deleteBranch(branchName) {
return Promise.resolve();
}
async mergeToLocal(branchName) {
const searchConfig = { state: 'open', branchName };
const change = await client_1.client
.findChanges(repository, searchConfig, true)
.then((res) => res.pop());
if (change) {
return super.mergeToLocal(change.revisions[change.current_revision].ref);
}
return super.mergeToLocal(branchName);
}
}
exports.GerritScm = GerritScm;
/**
* This function should generate a Gerrit Change-ID analogous to the commit hook. We avoid the commit hook cause of security concerns.
* random=$( (whoami ; hostname ; date; cat $1 ; echo $RANDOM) | git hash-object --stdin) prefixed with an 'I'.
* TODO: Gerrit don't accept longer Change-IDs (sha256), but what happens with this https://git-scm.com/docs/hash-function-transition/ ?
*/
function generateChangeId() {
return 'I' + (0, hash_1.hash)((0, crypto_1.randomUUID)(), 'sha1');
}
//# sourceMappingURL=scm.js.map