UNPKG

azdev-automation

Version:

Azure DevOps automation framework enables access control automation of projects, pipelines and repositories configuration in Azure DevOps Services

144 lines (143 loc) 8.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReleaseUpdater = void 0; class ReleaseUpdater { constructor(releaseHelper, taskAgentHelper, securityHelper, commonHelper, logger) { this.logger = logger; this.debugLogger = logger.extend(this.constructor.name); this.releaseHelper = releaseHelper; this.taskAgentHelper = taskAgentHelper; this.securityHelper = securityHelper; this.commonHelper = commonHelper; } async initialize(projectName) { this.logger.log("Initializing project classic release pipelines feature"); // Simply getting all release definitions initializes // Required classic release pipelines capabilities const result = this.releaseHelper.getDefinitions(projectName); } async removeDefinitionsArtifact(projectName, artifactName, artifactType, mock) { const debug = this.debugLogger.extend(this.removeDefinitionsArtifact.name); this.logger.log(`Updating <${projectName}> project release definition(s)`); const filteredDefinitions = await this.releaseHelper.findDefinitionsWithArtifact(projectName, artifactName, artifactType); if (filteredDefinitions.length === 0) { this.logger.log(`No definitions with <${artifactName}> artifact <${artifactType}> found`); return; } this.logger.log(`Found <${filteredDefinitions.length}> definition(s) with matching <${artifactName}> artifact`); await Promise.all(filteredDefinitions.map(async (definition) => { this.logger.log(`Updating <${definition.name}> definition artifact(s)`); const targetArtifacts = definition.artifacts.filter((a) => a.alias === artifactName); for (const artifact of targetArtifacts) { let version = "latest"; if (artifact.definitionReference.defaultVersionType.id === "specificVersionType") { version = artifact.definitionReference.defaultVersionSpecific.name; } this.logger.log(`Removing <${artifact.alias}> artifact <${artifact.definitionReference.branches.id}> branch <${version}> version`); const updatedDefinition = await this.releaseHelper.removeDefinitionArtifact(definition, artifact.alias, artifact.type); if (mock) { debug(`Definition <${definition.name}> (${definition.id}) will not be updated (MOCK)`); continue; } debug(`Updating <${definition.name}> definition <${artifact.alias}> artifact(s)`); await this.releaseHelper.updateDefinition(updatedDefinition, projectName); } })); } async removeDefinitionsTasks(name, projectName, task, mock) { const debug = this.debugLogger.extend(this.removeDefinitionsTasks.name); this.logger.log(`Updating <${projectName}> project <${name}> release definition(s)`); const tasks = await this.taskAgentHelper.findTasks(task.name); if (tasks.length < 0) { this.logger.log(`No tasks mathing <${task.name}> filter found`); return; } const filteredDefinitions = await this.releaseHelper.findDefinitionsWithTasks(name, projectName, tasks); if (filteredDefinitions.length === 0) { debug(`No project <${projectName}> definitions with <${task.name}> task(s) found`); return; } debug(`Found <${projectName}> project <${filteredDefinitions.length}> definitions`); for (const definition of filteredDefinitions) { const updatedDefinition = await this.releaseHelper.removeDefinitionTasks(definition, tasks); this.logger.log(`${projectName} | ${definition.name} | ${task.name}`); if (mock) { debug(`Definition <${definition.name}> (${definition.id}) will not be updated (MOCK)`); continue; } debug(`Removing <${definition.name}> definition task(s)`); await this.releaseHelper.updateDefinition(updatedDefinition, projectName); } } async updateDefinitionsTasks(name, projectName, task, releases, mock) { const debug = this.debugLogger.extend(this.updateDefinitionsTasks.name); this.logger.log(`Scanning <${projectName}> project <${name}> release definition(s)`); const tasks = await this.taskAgentHelper.findTasks(task.name); if (tasks.length <= 0) { debug(`No tasks mathing <${task.name}> filter found`); return; } debug(`Found <${tasks.length}> task(s) matching <${task.name}> filter`); const filteredDefinitions = await this.releaseHelper.findDefinitionsWithTasks(name, projectName, tasks); if (filteredDefinitions.length <= 0) { debug(`No definitions mathing <${name}> filter found`); return; } debug(`Found <${filteredDefinitions.length}> release definition(s) with matching task(s)`); await Promise.all(filteredDefinitions.map(async (definition) => { debug(`Updating <${definition.name}> (${definition.id}) definition task(s)`); const updatedDefinition = await this.releaseHelper.updateDefinitionTasks(definition, tasks, task.parameters, task.filter); // Push updated definition only if (updatedDefinition.comment) { if (mock) { this.logger.log(`Definition <${updatedDefinition.name}> (${definition.id}) update required (MOCK)`); } else { this.logger.log(`Updating <${updatedDefinition.name}> (${definition.id}) definition`); await this.releaseHelper.updateDefinition(updatedDefinition, projectName); } } else { debug(`Definition <${updatedDefinition.name}> (${definition.id}) update not required`); } if (releases) { const filteredReleases = await this.releaseHelper.findDefinitionReleasesWithTasks(definition.id, projectName, tasks); for (const release of filteredReleases) { debug(`Updating <${release.name}> (${release.id}) release task(s)`); const updatedRelease = await this.releaseHelper.updateReleaseTasks(release, tasks, task.parameters, task.filter); // Push updated release only if (updatedRelease.comment) { if (mock) { this.logger.log(`Release <${updatedRelease.name}> (${updatedRelease.id}) update required (MOCK)`); } else { this.logger.log(`Updating <${updatedRelease.name}> (${updatedRelease.id}) release`); await this.releaseHelper.updateRelease(updatedRelease, projectName); } } else { debug(`Release <${updatedRelease.name}> (${updatedRelease.id}) update not required`); } } } })); } async updatePermissions(project, policy) { const debug = this.debugLogger.extend(this.updatePermissions.name); this.logger.log(`Applying <${policy.name}> release permissions policy`); const namespace = await this.securityHelper.getNamespace("ReleaseManagement", "View release pipeline"); const permissionSetId = namespace.namespaceId; const permissionSetToken = project.id; const existingIdentities = await this.securityHelper.getExplicitIdentities(project.id, permissionSetId, permissionSetToken); await Promise.all(policy.definition.map(async (group) => { const groupName = `[${project.name}]\\${group.name}`; this.logger.log(`Assigninig <${groupName}> group permissions`); // Slow down parallel calls to address // Intermittent API connectivity issues await this.commonHelper.wait(500, 3000); const targetIdentity = await this.securityHelper.getExistingIdentity(groupName, project.id, existingIdentities); await this.securityHelper.updateIdentityPermissions(project.id, targetIdentity, group.permissions, permissionSetId, permissionSetToken); })); } } exports.ReleaseUpdater = ReleaseUpdater;