1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from os import path
from datetime import datetime
from jinja2 import Environment, FileSystemLoader, select_autoescape
from ..repository.github_repository_manager import GithubRepositoryManager
from ..base.base_github_manager import BaseGithubManager
from ..constants import (WINDOWS, PYTHON, NODE, DOTNET, POWERSHELL)
from ..exceptions import LanguageNotSupportException
class GithubYamlManager(BaseGithubManager):
def __init__(self, language, app_type, github_pat, github_repository):
super(GithubYamlManager, self).__init__(pat=github_pat)
self._github_repo_mgr = GithubRepositoryManager(pat=github_pat)
self._github_repository = github_repository
self._language = language
self._app_type = app_type
self.jinja_env = Environment(
loader=FileSystemLoader(path.join(path.abspath(path.dirname(__file__)), 'templates')),
autoescape=select_autoescape(['jinja'])
)
def create_yaml(self, overwrite=False):
if self._language == PYTHON:
language_str = 'python'
package_route = '$(System.DefaultWorkingDirectory)'
dependencies = self._python_dependencies()
elif self._language == NODE:
language_str = 'node'
package_route = '$(System.DefaultWorkingDirectory)'
dependencies = self._node_dependencies()
elif self._language == DOTNET:
language_str = 'dotnet'
package_route = '$(System.DefaultWorkingDirectory)/publish_output/s'
dependencies = self._dotnet_dependencies()
elif self._language == POWERSHELL:
language_str = 'powershell'
package_route = '$(System.DefaultWorkingDirectory)'
dependencies = self._powershell_dependencies()
else:
raise LanguageNotSupportException(self._language)
if self._app_type == WINDOWS:
platform_str = 'windows'
yaml = self._generate_yaml(dependencies, 'VS2017-Win2016', language_str, platform_str, package_route)
else:
platform_str = 'linux'
yaml = self._generate_yaml(dependencies, 'ubuntu-16.04', language_str, platform_str, package_route)
if overwrite:
return self._overwrite_yaml_file(yaml)
else:
return self._commit_yaml_file(yaml)
def _commit_yaml_file(self, data):
return self._github_repo_mgr.commit_file(
repository_fullname=self._github_repository,
file_path="azure-pipelines.yml",
file_data=data,
commit_message="Created azure-pipelines.yml by Azure CLI ({time})".format(
time=datetime.utcnow().strftime("%Y-%m-%d %X UTC")
),
)
def _overwrite_yaml_file(self, data):
sha = self._github_repo_mgr.get_content(
self._github_repository,
'azure-pipelines.yml',
get_metadata=True
).get("sha")
return self._github_repo_mgr.commit_file(
repository_fullname=self._github_repository,
file_path="azure-pipelines.yml",
file_data=data,
commit_message="Overwritten azure-pipelines.yml by Azure CLI ({time})".format(
time=datetime.utcnow().strftime("%Y-%m-%d %X UTC")
),
sha=sha
)
def _generate_yaml(self, dependencies, vmImage, language_str, platform_str, package_route):
template = self.jinja_env.get_template('build.jinja')
outputText = template.render(dependencies=dependencies, vmImage=vmImage,
language=language_str, platform=platform_str,
package_route=package_route)
return outputText
def _requires_extensions(self):
return self._github_repo_mgr.check_github_file(self._github_repository, 'extensions.csproj')
def _requires_pip(self):
return self._github_repo_mgr.check_github_file(self._github_repository, 'requirements.txt')
def _requires_npm(self):
return self._github_repo_mgr.check_github_file(self._github_repository, 'package.json')
def _inject_extensions_build(self, dependencies):
if self._app_type == WINDOWS:
runtime = 'win10-x64'
else:
runtime = 'ubuntu.16.04-x64'
dependencies.append("- task: DotNetCoreCLI@2")
dependencies.append(" displayName: '.NET Core build extensions'")
dependencies.append(" inputs:")
dependencies.append(" projects: extensions.csproj")
dependencies.append(" arguments: '--runtime {runtime} --output bin/'".format(runtime=runtime))
def _python_dependencies(self):
"""Helper to create the standard python dependencies"""
dependencies = []
if self._requires_extensions():
self._inject_extensions_build(dependencies)
dependencies.append('- task: UsePythonVersion@0')
dependencies.append(' displayName: "Setting python version to 3.6 as required by functions"')
dependencies.append(' inputs:')
dependencies.append(' versionSpec: \'3.6\'')
dependencies.append(' architecture: \'x64\'')
dependencies.append('- script: |')
dependencies.append(' python3.6 -m venv worker_venv')
dependencies.append(' source worker_venv/bin/activate')
dependencies.append(' pip3.6 install setuptools')
if self._requires_pip():
dependencies.append(' pip3.6 install -r requirements.txt')
return dependencies
def _node_dependencies(self):
"""Helper to create the standard node dependencies"""
dependencies = []
if self._requires_extensions():
self._inject_extensions_build(dependencies)
if self._requires_npm():
dependencies.append('- script: |')
dependencies.append(' npm install')
dependencies.append(' npm run build --if-present')
dependencies.append(' npm prune --production')
return dependencies
def _dotnet_dependencies(self):
"""Helper to create the standard dotnet dependencies"""
dependencies = []
dependencies.append('- script: |')
dependencies.append(' dotnet restore')
dependencies.append(' dotnet build --configuration Release')
dependencies.append("- task: DotNetCoreCLI@2")
dependencies.append(" inputs:")
dependencies.append(" command: publish")
dependencies.append(" arguments: '--configuration Release --output publish_output'")
dependencies.append(" projects: '*.csproj'")
dependencies.append(" publishWebProjects: false")
dependencies.append(" modifyOutputPath: true")
dependencies.append(" zipAfterPublish: false")
return dependencies
def _powershell_dependencies(self):
dependencies = []
if self._requires_extensions():
self._inject_extensions_build(dependencies)
return dependencies
|