From 5aba56c07482d9c035314ba55498bdcde8fe2319 Mon Sep 17 00:00:00 2001 From: dobromirts <46093564+dobromirts@users.noreply.github.com> Date: Tue, 16 Jul 2024 17:45:22 +0300 Subject: [PATCH] feat(*): Add azure pipelines (#5884) * feat(*): Add azure pipelines * chore(*): improve pipeline and combine templates * chore(*): add zip task combining build folders * chore(*): change pool to ubutu-latest * chore(*): add customCommand ci production false to install also dev deps * chore(*): replace npm ci with npm install * Troubleshooting in progress * Removed silly-level npm logging - no insight from it * Try gulp max logging * chore(*): update copyGitHooks function --------- Co-authored-by: Borislav Traykov --- azure-pipelines/azure-pipelines-en.yml | 70 +++++++++++++++++++++ azure-pipelines/azure-pipelines-jp-kr.yml | 75 +++++++++++++++++++++++ azure-pipelines/templates/build-tasks.yml | 35 +++++++++++ gulpfile.js | 68 ++++++++++---------- 4 files changed, 212 insertions(+), 36 deletions(-) create mode 100644 azure-pipelines/azure-pipelines-en.yml create mode 100644 azure-pipelines/azure-pipelines-jp-kr.yml create mode 100644 azure-pipelines/templates/build-tasks.yml diff --git a/azure-pipelines/azure-pipelines-en.yml b/azure-pipelines/azure-pipelines-en.yml new file mode 100644 index 0000000000..0c238bec8d --- /dev/null +++ b/azure-pipelines/azure-pipelines-en.yml @@ -0,0 +1,70 @@ +trigger: + branches: + include: + - vnext + - master + paths: + exclude: + - '**/jp/*' + - '**/kr/*' + +# This pipeline is meant to build specific branches for deployment. It's not meant to be a part of PR validation. Ensure that this pipeline is reserved for deployment purposes. +pr: none + +name: $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + - name: buildType + ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: + value: 'production' + ${{ else }}: + value: 'staging' # Intended for the vnext branch, but also available for manually triggering other branches + +parameters: +- name: isVerbose + displayName: 'Get verbose output from steps - where configurable' + type: boolean + default: false +- name: shouldCleanPostExecution + displayName: 'Clean all pipeline dirs after the pipeline finishes?' + type: boolean + default: true + +stages: + - stage: Build + displayName: Build Stage + jobs: + - job: Build + displayName: Build Job + pool: + vmImage: 'ubuntu-latest' + steps: + - checkout: self + clean: true + fetchTags: true + + - task: NodeTool@0 + displayName: Use Node 20.x + inputs: + versionSpec: 20.x + + - task: UseDotNet@2 + displayName: Use .NET Core sdk 6.x + inputs: + version: 6.x + + - template: templates/build-tasks.yml + parameters: + lang: en + isVerbose: ${{ parameters.isVerbose }} + buildType: $(buildType) + + - task: PublishPipelineArtifact@1 + displayName: 'Publish Pipeline Artifact' + inputs: + path: '$(Build.ArtifactStagingDirectory)' + artifactName: 'IgniteUIDocFX' + + - ${{ if eq(parameters.shouldCleanPostExecution, true) }}: + - task: PostBuildCleanup@4 + displayName: Clean Agent Directories diff --git a/azure-pipelines/azure-pipelines-jp-kr.yml b/azure-pipelines/azure-pipelines-jp-kr.yml new file mode 100644 index 0000000000..4120e29250 --- /dev/null +++ b/azure-pipelines/azure-pipelines-jp-kr.yml @@ -0,0 +1,75 @@ +trigger: + branches: + include: + - vnext + - master + paths: + exclude: + - '**/en/*' + +# This pipeline is meant to build specific branches for deployment. It's not meant to be a part of PR validation. Ensure that this pipeline is reserved for deployment purposes. +pr: none + +name: $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + - name: buildType + ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: + value: 'production' + ${{ else }}: + value: 'staging' # Intended for the vnext branch, but also available for manually triggering other branches + +parameters: +- name: isVerbose + displayName: 'Get verbose output from steps - where configurable' + type: boolean + default: false +- name: shouldCleanPostExecution + displayName: 'Clean all pipeline dirs after the pipeline finishes?' + type: boolean + default: true + +stages: + - stage: Build + displayName: Build Stage + jobs: + - job: Build + displayName: Build Job + pool: + vmImage: 'ubuntu-latest' + steps: + - checkout: self + clean: true + fetchTags: true + + - task: NodeTool@0 + displayName: Use Node 20.x + inputs: + versionSpec: 20.x + + - task: UseDotNet@2 + displayName: Use .NET Core sdk 6.x + inputs: + version: 6.x + + - template: templates/build-tasks.yml + parameters: + lang: jp + isVerbose: ${{ parameters.isVerbose }} + buildType: $(buildType) + + - template: templates/build-tasks.yml + parameters: + lang: kr + isVerbose: ${{ parameters.isVerbose }} + buildType: $(buildType) + + - task: PublishPipelineArtifact@1 + displayName: 'Publish Pipeline Artifact' + inputs: + path: '$(Build.ArtifactStagingDirectory)' + artifactName: 'IgniteUIDocFX' + + - ${{ if eq(parameters.shouldCleanPostExecution, true) }}: + - task: PostBuildCleanup@4 + displayName: Clean Agent Directories diff --git a/azure-pipelines/templates/build-tasks.yml b/azure-pipelines/templates/build-tasks.yml new file mode 100644 index 0000000000..bff30f0f09 --- /dev/null +++ b/azure-pipelines/templates/build-tasks.yml @@ -0,0 +1,35 @@ +parameters: + - name: lang + type: string + - name: isVerbose + type: boolean + default: false + - name: buildType + type: string + +steps: + - task: Npm@1 + displayName: 'npm ci' + inputs: + command: custom + workingDir: $(Build.SourcesDirectory) + verbose: ${{ parameters.isVerbose }} + customCommand: 'ci --production=false' + + - task: Npm@1 + displayName: npm build ${{ parameters.buildType }} ${{ parameters.lang }} + inputs: + command: custom + workingDir: $(Build.SourcesDirectory) + verbose: ${{ parameters.isVerbose }} + customCommand: run build-${{ parameters.buildType }} -- --lang=${{ parameters.lang }} + + - task: ArchiveFiles@2 + displayName: 'Package ${{ parameters.buildType }} ${{ parameters.lang }} - zip' + inputs: + verbose: ${{ parameters.isVerbose }} + rootFolderOrFile: $(Build.SourcesDirectory)/${{ parameters.lang }}/_site + includeRootFolder: false + archiveType: 'zip' + archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.buildType }}_${{ parameters.lang }}.zip + replaceExistingArchive: true diff --git a/gulpfile.js b/gulpfile.js index d7381ee74c..cc4a1e35c6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -196,55 +196,51 @@ const build = series( const buildCI = series(generateGridsTopics, generateTreeGridsTopics, generateHierarchicalGridsTopics, generatePivotGridsTopics, buildSite); const copyGitHooks = async (cb) => { - - if (process.env.AZURE_PIPELINES || process.env.TRAVIS || process.env.CI || !fs.existsSync('.git')) { + if (process.env.AZURE_PIPELINES || process.env.TRAVIS || process.env.CI || !(await exists('.git'))) { return; } - const gitHooksDir = './.git/hooks/'; - const defaultCopyHookDir = gitHooksDir + 'scripts/'; + const gitHooksDir = path.join('.git', 'hooks'); + const defaultCopyHookDir = path.join(gitHooksDir, 'scripts'); const dirs = [ gitHooksDir, defaultCopyHookDir, - defaultCopyHookDir + 'templates', - defaultCopyHookDir + 'templateValidators', - defaultCopyHookDir + 'utils' + path.join(defaultCopyHookDir, 'templates'), + path.join(defaultCopyHookDir, 'templateValidators'), + path.join(defaultCopyHookDir, 'utils') ]; - dirs.forEach((dir) => { - if (!fs.existsSync(dir)) { - fs.mkdir(dir, (err) => { - if (err) { - throw err; - } - }); + try { + for (const dir of dirs) { + if (!(await exists(dir))) { + await fs.mkdir(dir, { recursive: true }); + } } - }); - - const defaultHookDir = './.hooks/scripts/'; - - fs.copyFileSync(defaultHookDir + 'templates/default.js', - defaultCopyHookDir + 'templates/default.js'); - - fs.copyFileSync(defaultHookDir + 'templateValidators/default-style-validator.js', - defaultCopyHookDir + 'templateValidators/default-style-validator.js'); - fs.copyFileSync(defaultHookDir + 'utils/issue-validator.js', - defaultCopyHookDir + 'utils/issue-validator.js'); + const defaultHookDir = path.join('.hooks', 'scripts'); - fs.copyFileSync(defaultHookDir + 'utils/line-limits.js', - defaultCopyHookDir + 'utils/line-limits.js'); + await fs.copyFile(path.join(defaultHookDir, 'templates', 'default.js'), path.join(defaultCopyHookDir, 'templates', 'default.js')); + await fs.copyFile(path.join(defaultHookDir, 'templateValidators', 'default-style-validator.js'), path.join(defaultCopyHookDir, 'templateValidators', 'default-style-validator.js')); + await fs.copyFile(path.join(defaultHookDir, 'utils', 'issue-validator.js'), path.join(defaultCopyHookDir, 'utils', 'issue-validator.js')); + await fs.copyFile(path.join(defaultHookDir, 'utils', 'line-limits.js'), path.join(defaultCopyHookDir, 'utils', 'line-limits.js')); + await fs.copyFile(path.join(defaultHookDir, 'common.js'), path.join(defaultCopyHookDir, 'common.js')); + await fs.copyFile(path.join(defaultHookDir, 'validate.js'), path.join(defaultCopyHookDir, 'validate.js')); + await fs.copyFile(path.join('.hooks', 'prepare-commit-msg'), path.join(gitHooksDir, 'prepare-commit-msg')); - fs.copyFileSync(defaultHookDir + 'common.js', - defaultCopyHookDir + 'common.js'); - - fs.copyFileSync(defaultHookDir + 'validate.js', - defaultCopyHookDir + 'validate.js'); - - fs.copyFileSync('./.hooks/prepare-commit-msg', - './.git/hooks/prepare-commit-msg'); + await cb(); + } catch (err) { + console.error('Error copying git hooks:', err); + throw err; + } +}; - return await cb(); +const exists = async (path) => { + try { + await fs.access(path); + return true; + } catch { + return false; + } }; exports.buildCI = buildCI;