├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── CI.yml │ └── codeql-analysis.yml ├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Directory.Build.props ├── GitVersion.yml ├── LICENSE ├── README.md ├── nuget.config └── src ├── .editorconfig ├── AzurePipelinesToGitHubActionsConverter.Core ├── AzurePipelinesModel │ ├── AzurePipelinesRoot.cs │ ├── Canary.cs │ ├── Containers.cs │ ├── Deploy.cs │ ├── Environment.cs │ ├── IncludeExclude.cs │ ├── Job.cs │ ├── On.cs │ ├── Parameter.cs │ ├── Pipelines.cs │ ├── Pool.cs │ ├── Repositories.cs │ ├── Resources.cs │ ├── Rolling.cs │ ├── RunOnce.cs │ ├── Schedule.cs │ ├── Stage.cs │ ├── Step.cs │ ├── Strategy.cs │ ├── Target.cs │ ├── Trigger.cs │ ├── Variable.cs │ └── Workspace.cs ├── AzurePipelinesToGitHubActionsConverter.Core.csproj ├── Conversion.cs ├── ConversionResponse.cs ├── GlobalSuppressions.cs ├── PipelinesToActionsConversion │ ├── ConditionsProcessing.cs │ ├── ConversionUtility.cs │ ├── GeneralProcessing.cs │ ├── JobProcessing.cs │ ├── StagesProcessing.cs │ ├── StepsProcessing.cs │ ├── StrategyProcessing.cs │ ├── SystemVariableProcessing.cs │ ├── TriggerProcessing.cs │ └── VariablesProcessing.cs └── Serialization │ ├── GitHubActionsSerialization.cs │ ├── JSONSerialization.cs │ └── YamlSerialization.cs ├── AzurePipelinesToGitHubActionsConverter.Tests ├── AzurePipelinesToGitHubActionsConverter.Tests.csproj ├── CompletePipelineTests.cs ├── ConditionTests.cs ├── ContainerTests.cs ├── FolderOfYAMLFilesTests.cs ├── GitHubSerializationTests.cs ├── JobsTests.cs ├── OctopusDeployTests.cs ├── PipelineTests.cs ├── PoolTests.cs ├── ResourcesTests.cs ├── StagesTests.cs ├── StepsAzureTests.cs ├── StepsContainerTests.cs ├── StepsDotNetTests.cs ├── StepsMiscTests.cs ├── StepsScriptingTests.cs ├── StepsTerraformTests.cs ├── StepsUnfinishedTests.cs ├── StrategyTests.cs ├── TemplateTests.cs ├── TriggerTests.cs ├── UtilityTests.cs ├── VariableTests.cs ├── filesNotCurrentlyWorking │ ├── deploy-to-existing-kubernetes-cluster-devspaces.yml │ ├── deploy-to-existing-kubernetes-cluster.yml │ ├── docker-container-to-aks.yml │ └── xcode.yml └── yamlFiles │ ├── .net-desktop.yml │ ├── android.yml │ ├── ant.yml │ ├── asp.net-core-.net-framework.yml │ ├── asp.net-core-functionapp-to-windows-on-azure.yml │ ├── asp.net-core.yml │ ├── asp.net.yml │ ├── docker-build.yml │ ├── docker-container-functionapp.yml │ ├── docker-container-to-acr.yml │ ├── docker-container-webapp.yml │ ├── docker-container.yml │ ├── empty.yml │ ├── gcc.yml │ ├── go.yml │ ├── gradle.yml │ ├── html.yml │ ├── jekyll-container.yml │ ├── maven-webapp-to-linux-on-azure.yml │ ├── maven.yml │ ├── node.js-express-webapp-to-linux-on-azure.yml │ ├── node.js-functionapp-to-linux-on-azure.yml │ ├── node.js-react-webapp-to-linux-on-azure.yml │ ├── node.js-with-angular.yml │ ├── node.js-with-grunt.yml │ ├── node.js-with-gulp.yml │ ├── node.js-with-react.yml │ ├── node.js-with-vue.yml │ ├── node.js-with-webpack.yml │ ├── node.js.yml │ ├── php-webapp-to-linux-on-azure.yml │ ├── php.yml │ ├── powershell-functionapp-to-windows-on-azure.yml │ ├── python-django.yml │ ├── python-functionapp-to-linux-on-azure.yml │ ├── python-package.yml │ ├── python-to-linux-webapp-on-azure.yml │ ├── ruby.yml │ ├── universal-windows-platform.yml │ ├── xamarin.android.yml │ └── xamarin.ios.yml ├── AzurePipelinesToGitHubActionsConverter.sln └── BuildVersion.ps1 /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.202.5/containers/dotnet/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] .NET version: 6.0, 5.0, 3.1, 6.0-bullseye, 5.0-bullseye, 3.1-bullseye, 6.0-focal, 5.0-focal, 3.1-focal 4 | ARG VARIANT="6.0-bullseye-slim" 5 | FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT} 6 | 7 | # [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 8 | ARG NODE_VERSION="none" 9 | RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi 10 | 11 | # [Optional] Uncomment this section to install additional OS packages. 12 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 13 | # && apt-get -y install --no-install-recommends 14 | 15 | # [Optional] Uncomment this line to install global node packages. 16 | # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.202.5/containers/dotnet 3 | { 4 | "name": "C# (.NET)", 5 | "runArgs": ["--init"], 6 | "build": { 7 | "dockerfile": "Dockerfile", 8 | "args": { 9 | // Update 'VARIANT' to pick a .NET Core version: 3.1, 5.0, 6.0 10 | // Append -bullseye or -focal to pin to an OS version. 11 | "VARIANT": "6.0", 12 | // Options 13 | "NODE_VERSION": "none" 14 | } 15 | }, 16 | 17 | // Set *default* container specific settings.json values on container create. 18 | "settings": {}, 19 | 20 | // Add the IDs of extensions you want installed when the container is created. 21 | "extensions": [ 22 | "ms-dotnettools.csharp", 23 | "ms-vscode.test-adapter-converter", 24 | "formulahendry.dotnet-test-explorer", 25 | "GitHub.copilot" 26 | ], 27 | 28 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 29 | // "forwardPorts": [5000, 5001], 30 | 31 | // [Optional] To reuse of your local HTTPS dev cert: 32 | // 33 | // 1. Export it locally using this command: 34 | // * Windows PowerShell: 35 | // dotnet dev-certs https --trust; dotnet dev-certs https -ep "$env:USERPROFILE/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" 36 | // * macOS/Linux terminal: 37 | // dotnet dev-certs https --trust; dotnet dev-certs https -ep "${HOME}/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" 38 | // 39 | // 2. Uncomment these 'remoteEnv' lines: 40 | // "remoteEnv": { 41 | // "ASPNETCORE_Kestrel__Certificates__Default__Password": "SecurePwdGoesHere", 42 | // "ASPNETCORE_Kestrel__Certificates__Default__Path": "/home/vscode/.aspnet/https/aspnetapp.pfx", 43 | // }, 44 | // 45 | // 3. Do one of the following depending on your scenario: 46 | // * When using GitHub Codespaces and/or Remote - Containers: 47 | // 1. Start the container 48 | // 2. Drag ~/.aspnet/https/aspnetapp.pfx into the root of the file explorer 49 | // 3. Open a terminal in VS Code and run "mkdir -p /home/vscode/.aspnet/https && mv aspnetapp.pfx /home/vscode/.aspnet/https" 50 | // 51 | // * If only using Remote - Containers with a local container, uncomment this line instead: 52 | // "mounts": [ "source=${env:HOME}${env:USERPROFILE}/.aspnet/https,target=/home/vscode/.aspnet/https,type=bind" ], 53 | 54 | // Use 'postCreateCommand' to run commands after the container is created. 55 | "postCreateCommand": "dotnet restore src/AzurePipelinesToGitHubActionsConverter.sln", 56 | 57 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 58 | "remoteUser": "vscode", 59 | "features": { 60 | "git": "latest" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/src/AzurePipelinesToGitHubActionsConverter.Core" 5 | schedule: 6 | interval: daily 7 | time: "06:00" 8 | timezone: America/New_York 9 | open-pull-requests-limit: 10 10 | assignees: 11 | - "samsmithnz" 12 | groups: 13 | core: 14 | patterns: ["*"] 15 | update-types: ["minor", "patch"] 16 | # Maintain dependencies for GitHub Actions 17 | - package-ecosystem: "github-actions" 18 | directory: "/" 19 | schedule: 20 | interval: "daily" 21 | time: "06:00" 22 | timezone: America/New_York 23 | open-pull-requests-limit: 10 24 | assignees: 25 | - "samsmithnz" 26 | groups: 27 | actions: 28 | patterns: ["*"] 29 | update-types: ["minor", "patch"] 30 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: 'CI/ CD' 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | strategy: 11 | matrix: 12 | os: [windows-latest, ubuntu-latest] 13 | runs-on: ${{matrix.os}} 14 | outputs: # https://stackoverflow.com/questions/59175332/using-output-from-a-previous-job-in-a-new-one-in-a-github-action 15 | Version: ${{ steps.gitversion.outputs.SemVer }} 16 | CommitsSinceVersionSource: ${{ steps.gitversion.outputs.CommitsSinceVersionSource }} 17 | steps: 18 | 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 #fetch-depth is needed for GitVersion 22 | 23 | #Install and calculate the new version with GitVersion 24 | - name: Install GitVersion 25 | uses: gittools/actions/gitversion/setup@v3.2.1 26 | with: 27 | versionSpec: 5.x 28 | 29 | - name: Determine Version 30 | uses: gittools/actions/gitversion/execute@v3.2.1 31 | id: gitversion # step id used as reference for output values 32 | 33 | - name: Display GitVersion outputs 34 | run: | 35 | echo "Version: ${{ steps.gitversion.outputs.SemVer }}" 36 | echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.CommitsSinceVersionSource }}" 37 | 38 | - name: Setup .NET 39 | uses: actions/setup-dotnet@v4 40 | with: 41 | dotnet-version: 8.0.x 42 | - name: .NET test 43 | run: dotnet test src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj -c Release --nologo -p:CollectCoverage=true -p:CoverletOutput=TestResults/ -p:CoverletOutputFormat=lcov -l:"trx;LogFileName=${{ github.workspace }}/TestOutput.xml" 44 | - name: Output results 45 | #if: runner.OS == 'Linux' 46 | shell: pwsh 47 | run: | 48 | [xml]$result = Get-Content -Path ${{ github.workspace }}/TestOutput.xml 49 | #$result.TestRun.ResultSummary.Counters.passed 50 | #$result.TestRun.ResultSummary.Counters.failed 51 | echo "Test results" >> $env:GITHUB_STEP_SUMMARY 52 | echo "" >> $env:GITHUB_STEP_SUMMARY # this is a blank line 53 | echo "- Total: $($result.TestRun.ResultSummary.Counters.total)" >> $env:GITHUB_STEP_SUMMARY 54 | echo "- Passed ✅: $($result.TestRun.ResultSummary.Counters.passed)" >> $env:GITHUB_STEP_SUMMARY 55 | echo "- Failed ❌: $($result.TestRun.ResultSummary.Counters.failed)" >> $env:GITHUB_STEP_SUMMARY 56 | - name: Publish coverage report to coveralls.io 57 | uses: coverallsapp/github-action@master 58 | if: runner.OS == 'Linux' && 0 == 1 #Only push the Linux coverage 59 | with: 60 | github-token: ${{ secrets.GITHUB_TOKEN }} 61 | path-to-lcov: src/AzurePipelinesToGitHubActionsConverter.Tests/TestResults/coverage.info 62 | 63 | #Pack the code into a NuGet package 64 | - name: .NET pack 65 | run: dotnet pack src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesToGitHubActionsConverter.Core.csproj -c Release --nologo --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' 66 | 67 | - name: Upload nuget package back to GitHub 68 | uses: actions/upload-artifact@v4 69 | if: runner.OS == 'Linux' #Only pack the Linux nuget package 70 | with: 71 | name: nugetPackage 72 | path: src/AzurePipelinesToGitHubActionsConverter.Core/bin/Release 73 | 74 | 75 | sonarCloud: 76 | name: Run SonarCloud analysis 77 | runs-on: ubuntu-latest 78 | if: github.ref == 'refs/heads/main' 79 | steps: 80 | - name: Run Sonarcloud test 81 | uses: samsmithnz/SamsDotNetSonarCloudAction@v2 82 | with: 83 | projects: 'src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesToGitHubActionsConverter.Core.csproj,src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj' 84 | dotnet-version: '8.0.x' 85 | sonarcloud-organization: samsmithnz-github 86 | sonarcloud-project: samsmithnz_AzurePipelinesToGitHubActionsConverter 87 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 88 | 89 | 90 | NuGetPush: 91 | runs-on: ubuntu-latest 92 | needs: 93 | - build 94 | - sonarCloud 95 | if: github.ref == 'refs/heads/main' 96 | steps: 97 | - name: Display GitVersion outputs 98 | run: | 99 | echo "Version: ${{ needs.build.outputs.Version }}" 100 | echo "CommitsSinceVersionSource: ${{ needs.build.outputs.CommitsSinceVersionSource }}" 101 | - name: Download nuget package artifact 102 | uses: actions/download-artifact@v4 103 | with: 104 | name: nugetPackage 105 | path: nugetPackage 106 | - name: Setup .NET 107 | uses: actions/setup-dotnet@v4 108 | with: 109 | dotnet-version: 6.0.x 110 | - name: Create Release 111 | id: create_release 112 | uses: actions/create-release@v1 113 | if: needs.build.outputs.CommitsSinceVersionSource > 0 #Only create a release if there has been a commit/version change 114 | env: 115 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 116 | with: 117 | tag_name: "v${{ needs.build.outputs.Version }}" 118 | release_name: "v${{ needs.build.outputs.Version }}" 119 | - name: Publish nuget package to nuget.org 120 | if: needs.build.outputs.CommitsSinceVersionSource > 0 #Only publish a NuGet package if there has been a commit/version change 121 | run: dotnet nuget push nugetPackage\*.nupkg --api-key "${{ secrets.GHPackagesToken }}" --source "https://api.nuget.org/v3/index.json" 122 | shell: pwsh 123 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '29 22 * * 1' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'csharp' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v4 39 | 40 | - name: Setup .NET 41 | uses: actions/setup-dotnet@v4 42 | with: 43 | dotnet-version: 8.0.x 44 | 45 | # Initializes the CodeQL tools for scanning. 46 | - name: Initialize CodeQL 47 | uses: github/codeql-action/init@v3 48 | with: 49 | languages: ${{ matrix.language }} 50 | # If you wish to specify custom queries, you can do so here or in a config file. 51 | # By default, queries listed here will override any specified in a config file. 52 | # Prefix the list here with "+" to use these queries and those in the config file. 53 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 54 | 55 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 56 | # If this step fails, then you should remove it and run the build manually (see below) 57 | - name: Autobuild 58 | uses: github/codeql-action/autobuild@v3 59 | 60 | # ℹ️ Command-line programs to run using the OS shell. 61 | # 📚 https://git.io/JvXDl 62 | 63 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 64 | # and modify them (or add more) to build your code if your project 65 | # uses a compiled language 66 | 67 | #- run: | 68 | # make bootstrap 69 | # make release 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v3 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | // Use IntelliSense to find out which attributes exist for C# debugging 6 | // Use hover for the description of the existing attributes 7 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/src/AzurePipelinesToGitHubActionsConverter.Tests/bin/Debug/net5.0/AzurePipelinesToGitHubActionsConverter.Tests.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/src/AzurePipelinesToGitHubActionsConverter.Tests", 16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console 17 | "console": "internalConsole", 18 | "stopAtEntry": false 19 | }, 20 | { 21 | "name": ".NET Core Attach", 22 | "type": "coreclr", 23 | "request": "attach" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotnet-test-explorer.testProjectPath": "**/*Tests.@(csproj|vbproj|fsproj)" 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "${workspaceFolder}/src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj", 36 | "/property:GenerateFullPaths=true", 37 | "/consoleloggerparameters:NoSummary" 38 | ], 39 | "problemMatcher": "$msCompile" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at samsmithnz@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 2 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9.0 5 | 6 | 7 | 8 | 9 | 10 | false 11 | 12 | 13 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | next-version: 1.3.0 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sam Smith (Microsoft) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | # Rules in this file were initially inferred by Visual Studio IntelliCode from the C:\Users\samsmit\source\repos\AzurePipelinesToGitHubActionsConverter\src codebase based on best match to current usage at 1/18/2021 2 | # You can modify the rules from these initially generated values to suit your own policies 3 | # You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference 4 | [*.cs] 5 | 6 | 7 | #Core editorconfig formatting - indentation 8 | 9 | #use soft tabs (spaces) for indentation 10 | indent_style = space 11 | 12 | #Formatting - indentation options 13 | 14 | #indent switch case contents. 15 | csharp_indent_case_contents = true 16 | #indent switch labels 17 | csharp_indent_switch_labels = true 18 | 19 | #Formatting - new line options 20 | 21 | #place catch statements on a new line 22 | csharp_new_line_before_catch = true 23 | #place else statements on a new line 24 | csharp_new_line_before_else = true 25 | #require members of object intializers to be on separate lines 26 | csharp_new_line_before_members_in_object_initializers = true 27 | #require braces to be on a new line for methods, control_blocks, object_collection_array_initializers, and types (also known as "Allman" style) 28 | csharp_new_line_before_open_brace = methods, control_blocks, object_collection_array_initializers, types 29 | 30 | #Formatting - organize using options 31 | 32 | #do not place System.* using directives before other using directives 33 | dotnet_sort_system_directives_first = false 34 | 35 | #Formatting - spacing options 36 | 37 | #require a space after a keyword in a control flow statement such as a for loop 38 | csharp_space_after_keywords_in_control_flow_statements = true 39 | #remove space within empty argument list parentheses 40 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 41 | #remove space between method call name and opening parenthesis 42 | csharp_space_between_method_call_name_and_opening_parenthesis = false 43 | #do not place space characters after the opening parenthesis and before the closing parenthesis of a method call 44 | csharp_space_between_method_call_parameter_list_parentheses = false 45 | #remove space within empty parameter list parentheses for a method declaration 46 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 47 | #place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list. 48 | csharp_space_between_method_declaration_parameter_list_parentheses = false 49 | 50 | #Formatting - wrapping options 51 | 52 | #leave code block on single line 53 | csharp_preserve_single_line_blocks = true 54 | 55 | #Style - Code block preferences 56 | 57 | #prefer curly braces even for one line of code 58 | csharp_prefer_braces = true:error 59 | 60 | #Style - expression bodied member options 61 | 62 | #prefer block bodies for constructors 63 | csharp_style_expression_bodied_constructors = false:suggestion 64 | #prefer block bodies for methods 65 | csharp_style_expression_bodied_methods = false:suggestion 66 | 67 | #Style - expression level options 68 | 69 | #prefer out variables to be declared before the method call 70 | csharp_style_inlined_variable_declaration = false:suggestion 71 | #prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them 72 | dotnet_style_predefined_type_for_member_access = true:suggestion 73 | 74 | #Style - Expression-level preferences 75 | 76 | #prefer objects to be initialized using object initializers when possible 77 | dotnet_style_object_initializer = true:suggestion 78 | 79 | #Style - implicit and explicit types 80 | 81 | #prefer explicit type over var in all cases, unless overridden by another code style rule 82 | csharp_style_var_elsewhere = false:suggestion 83 | #prefer explicit type over var to declare variables with built-in system types such as int 84 | csharp_style_var_for_built_in_types = false:suggestion 85 | #prefer explicit type over var when the type is already mentioned on the right-hand side of a declaration 86 | csharp_style_var_when_type_is_apparent = false:suggestion 87 | 88 | #Style - language keyword and framework type options 89 | 90 | #prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them 91 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 92 | 93 | #Style - modifier options 94 | 95 | #prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods. 96 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion 97 | 98 | #Style - Modifier preferences 99 | 100 | #when this rule is set to a list of modifiers, prefer the specified ordering. 101 | csharp_preferred_modifier_order = public,private,static,readonly:suggestion 102 | 103 | #Style - qualification options 104 | 105 | #prefer fields not to be prefaced with this. or Me. in Visual Basic 106 | dotnet_style_qualification_for_field = false:suggestion 107 | #prefer methods not to be prefaced with this. or Me. in Visual Basic 108 | dotnet_style_qualification_for_method = false:suggestion 109 | 110 | #'new' expression can be simplified 111 | dotnet_diagnostic.IDE0090.severity = none -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/AzurePipelinesRoot.cs: -------------------------------------------------------------------------------- 1 | //using System.Collections.Generic; 2 | 3 | ////#Example Pipeline YAML: 4 | ////trigger: 5 | ////- main 6 | 7 | ////pool: 8 | //// vmImage: ubuntu-latest 9 | 10 | ////variables: 11 | //// buildConfiguration: Release 12 | 13 | ////steps: 14 | ////- script: dotnet build --configuration $(buildConfiguration) WebApplication1/WebApplication1.Service/WebApplication1.Service.csproj 15 | //// displayName: dotnet build $(buildConfiguration) 16 | 17 | //namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 18 | //{ 19 | // //name: string # build numbering format 20 | // //resources: 21 | // // containers: [ containerResource ] 22 | // // repositories: [ repositoryResource ] 23 | // //variables: { string: string } | [ variable | templateReference ] 24 | // //trigger: trigger 25 | // //pr: pr 26 | // //stages: [ stage | templateReference ] 27 | 28 | // public class AzurePipelinesRoot 29 | // { 30 | // public string name { get; set; } 31 | 32 | // public Dictionary parameters { get; set; } 33 | 34 | // public string container { get; set; } 35 | // public Resources resources { get; set; } 36 | 37 | // //Trigger is a complicated case, where it can be a simple list, or a more complex trigger object 38 | // //To solve this, we added a generic to try to convert to a string[], and failing that, try to convert with Trigger 39 | // //All outputs will return the complex version 40 | // //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#triggers 41 | // public TTriggers trigger { get; set; } 42 | // //public string[] trigger { get; set; } 43 | // //public Trigger trigger { get; set; } 44 | 45 | // public Trigger pr { get; set; } 46 | // public Schedule[] schedules { get; set; } 47 | // public Pool pool { get; set; } 48 | 49 | // public Strategy strategy { get; set; } 50 | 51 | // //Variables is similar to triggers, this can be a simple list, or a more complex variable object 52 | // public TVariables variables { get; set; } 53 | // //public Dictionary variables { get; set; } 54 | 55 | // public Stage[] stages { get; set; } 56 | // public Job[] jobs { get; set; } 57 | // public Step[] steps { get; set; } 58 | // //TODO: There is currently no conversion path for services 59 | // public Dictionary services { get; set; } 60 | // } 61 | //} 62 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Canary.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Canary 4 | { 5 | public int[] increments { get; set; } 6 | public Deploy preDeploy { get; set; } 7 | public Deploy deploy { get; set; } 8 | public Deploy routeTraffic { get; set; } 9 | public Deploy postRouteTraffic { get; set; } 10 | public On on { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Containers.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 4 | { 5 | //containers: 6 | //- container: string # identifier (A-Z, a-z, 0-9, and underscore) 7 | // image: string # container image name 8 | // options: string # arguments to pass to container at startup 9 | // endpoint: string # reference to a service connection for the private registry 10 | // env: { string: string } # list of environment variables to add 11 | // ports: [ string ] # ports to expose on the container 12 | // volumes: [ string ] # volumes to mount on the container 13 | public class Containers 14 | { 15 | //TODO: There is currently no conversion path for containers 16 | public string container { get; set; } 17 | public string image { get; set; } 18 | public string options { get; set; } 19 | public string endpoint { get; set; } 20 | public Dictionary env { get; set; } 21 | public string[] ports { get; set; } 22 | public string[] volumes { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Deploy.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Deploy 4 | { 5 | public Pool pool { get; set; } 6 | public Step[] steps { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Environment.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#environment 4 | //environment: # create environment and/or record deployments 5 | // name: string # name of the environment to run this job on. 6 | // resourceName: string # name of the resource in the environment to record the deployments against 7 | // resourceId: number # resource identifier 8 | // resourceType: string # type of the resource you want to target. Supported types - virtualMachine, Kubernetes 9 | // tags: string | [ string ] # tag names to filter the resources in the environment 10 | // 11 | //Technically can also be a simple string, but we replace that in the intial conversion 12 | //environment: environmentName.resourceName 13 | 14 | public class Environment 15 | { 16 | public string name { get; set; } 17 | public string resourceName { get; set; } 18 | public string resourceId { get; set; } 19 | public string resourceType { get; set; } 20 | public string[] tags { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/IncludeExclude.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class IncludeExclude 4 | { 5 | public string[] include { get; set; } 6 | public string[] exclude { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Job.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 5 | { 6 | public class Job 7 | { 8 | //Regular job: 9 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#job 10 | //jobs: 11 | //- job: string # name of the job, A-Z, a-z, 0-9, and underscore 12 | // displayName: string # friendly name to display in the UI 13 | // dependsOn: string | [ string ] 14 | // condition: string 15 | // strategy: 16 | // parallel: # parallel strategy, see below 17 | // matrix: # matrix strategy, see below 18 | // maxParallel: number # maximum number of matrix jobs to run simultaneously 19 | // continueOnError: boolean # 'true' if future jobs should run even if this job fails; defaults to 'false' 20 | // pool: pool # see pool schema 21 | // workspace: 22 | // clean: outputs | resources | all # what to clean up before the job runs 23 | // container: containerReference # container to run this job inside 24 | // timeoutInMinutes: number # how long to run the job before automatically cancelling 25 | // cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them 26 | // variables: { string: string } | [ variable | variableReference ] 27 | // steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ] 28 | // services: { string: string | container } # container resources to run as a service container 29 | public string job { get; set; } 30 | public string displayName { get; set; } 31 | public string[] dependsOn { get; set; } 32 | [DefaultValue("succeeded()")] 33 | public string condition { get; set; } //https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?tabs=yaml&view=azure-devops 34 | public Strategy strategy { get; set; } 35 | public bool continueOnError { get; set; } 36 | public Pool pool { get; set; } 37 | public Workspace workspace { get; set; } 38 | public Containers container { get; set; } 39 | [DefaultValue(0)] 40 | public int timeoutInMinutes { get; set; } = 0; 41 | [DefaultValue(1)] 42 | public int cancelTimeoutInMinutes { get; set; } = 1; 43 | public Dictionary variables { get; set; } 44 | public Step[] steps { get; set; } 45 | //TODO: There is currently no conversion path for services 46 | public Dictionary services { get; set; } 47 | 48 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#deployment-job 49 | //Deployment job 50 | //jobs: 51 | //- deployment: string # name of the deployment job (A-Z, a-z, 0-9, and underscore) 52 | // displayName: string # friendly name to display in the UI 53 | // pool: # see the following "Pool" schema 54 | // name: string 55 | // demands: string | [ string ] 56 | // workspace: 57 | // clean: outputs | resources | all # what to clean up before the job runs 58 | // dependsOn: string 59 | // condition: string 60 | // continueOnError: boolean # 'true' if future jobs should run even if this job fails; defaults to 'false' 61 | // container: containerReference # container to run this job inside 62 | // services: { string: string | container } # container resources to run as a service container 63 | // timeoutInMinutes: nonEmptyString # how long to run the job before automatically cancelling 64 | // cancelTimeoutInMinutes: nonEmptyString # how much time to give 'run always even if cancelled tasks' before killing them 65 | // variables: # several syntaxes, see specific section 66 | // environment: string # target environment name and optionally a resource name to record the deployment history; format: . 67 | // strategy: 68 | // runOnce: #rolling, canary are the other strategies that are supported 69 | // deploy: 70 | // steps: 71 | // - script: [ script | bash | pwsh | powershell | checkout | task | templateReference ] 72 | public string deployment { get; set; } 73 | public Environment environment { get; set; } 74 | 75 | public string template { get; set; } 76 | public Dictionary parameters { get; set; } 77 | 78 | //Not strictly part of the Azure Pipelines Job schema, but it's useful for us to save this as we build the new GitHub job name when stages are involved 79 | public string stageName { get; set; } 80 | 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/On.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class On 4 | { 5 | public Deploy failure { get; set; } 6 | public Deploy success { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Parameter.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Parameter 4 | { 5 | public string name { get; set; } 6 | public string displayName { get; set; } 7 | public string type { get; set; } 8 | public string @default { get; set; } 9 | public string[] values { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Pipelines.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //pipelines: 4 | //- pipeline: string # identifier for the pipeline resource 5 | // project: string # project for the build pipeline; optional input for current project 6 | // source: string # source pipeline definition name 7 | // branch: string # branch to pick the artifact, optional; defaults to all branches 8 | // version: string # pipeline run number to pick artifact; optional; defaults to last successfully completed run 9 | // trigger: # optional; Triggers are not enabled by default. 10 | // branches: 11 | // include: [string] # branches to consider the trigger events, optional; defaults to all branches. 12 | // exclude: [string] # branches to discard the trigger events, optional; defaults to none. 13 | //TODO: There is currently no conversion path for pipelines 14 | public class Pipelines 15 | { 16 | public string pipeline { get; set; } 17 | public string project { get; set; } 18 | public string source { get; set; } 19 | public string branch { get; set; } 20 | public string version { get; set; } 21 | public Trigger trigger { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Pool.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //pool: 4 | // name: string # name of the pool to run this job in 5 | // demands: string # see the following "Demands" topic 6 | // vmImage: string # name of the VM image you want to use; valid only in the Microsoft-hosted pool 7 | 8 | //OR 9 | 10 | //pool: 11 | // name: string # name of the pool to run this job in 12 | // demands: [ string ] # see the following "Demands" topic 13 | // vmImage: string # name of the VM image you want to use; valid only in the Microsoft-host 14 | 15 | //Note that there is a 3rd variation, that is just a Pool name (e.g. a string) 16 | public class Pool 17 | { 18 | public string vmImage { get; set; } 19 | public string name { get; set; } 20 | public string[] demands { get; set; } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Repositories.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#resources 4 | //resources: 5 | // repositories: 6 | // - repository: string # identifier (A-Z, a-z, 0-9, and underscore) 7 | // type: enum # see the following "Type" topic 8 | // name: string # repository name (format depends on `type`) 9 | // ref: string # ref name to use; defaults to 'refs/heads/main' 10 | // endpoint: string # name of the service connection to use (for types that aren't Azure Repos) 11 | // trigger: # CI trigger for this repository, no CI trigger if skipped (only works for Azure Repos) 12 | // branches: 13 | // include: [ string ] # branch names which will trigger a build 14 | // exclude: [ string ] # branch names which will not 15 | // tags: 16 | // include: [ string ] # tag names which will trigger a build 17 | // exclude: [ string ] # tag names which will not 18 | // paths: 19 | // include: [ string ] # file paths which must match to trigger a build 20 | // exclude: [ string ] # file paths which will not trigger a build 21 | public class Repositories 22 | { 23 | public string repository { get; set; } 24 | public string type { get; set; } 25 | public string name { get; set; } 26 | //as "ref" is a reserved word in C#, added an "_", and remove this "_" when serializing 27 | public string _ref { get; set; } 28 | public string endpoint { get; set; } 29 | public string connection { get; set; } 30 | public string source { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Resources.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#resources 4 | public class Resources 5 | { 6 | //TODO: There is currently no conversion path for resources 7 | public Pipelines[] pipelines { get; set; } 8 | public Repositories[] repositories { get; set; } 9 | public Containers[] containers { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Rolling.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Rolling 4 | { 5 | public int maxParallel { get; set; } 6 | public Deploy preDeploy { get; set; } 7 | public Deploy deploy { get; set; } 8 | public Deploy routeTraffic { get; set; } 9 | public Deploy postRouteTraffic { get; set; } 10 | public On on { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/RunOnce.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class RunOnce 4 | { 5 | public Deploy preDeploy { get; set; } 6 | public Deploy deploy { get; set; } 7 | public Deploy routeTraffic { get; set; } 8 | public Deploy postRouteTraffic { get; set; } 9 | public On on { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Schedule.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //schedules: 4 | //- cron: string # cron syntax defining a schedule in UTC time 5 | // displayName: string # friendly name given to a specific schedule 6 | // branches: 7 | // include: [ string ] # which branches the schedule applies to 8 | // exclude: [ string ] # which branches to exclude from the schedule 9 | // always: boolean # whether to always run the pipeline or only if there have been source code changes since the last successful scheduled run. The default is false. 10 | public class Schedule 11 | { 12 | public string cron { get; set; } 13 | public string displayName { get; set; } 14 | public IncludeExclude branches { get; set; } 15 | public bool always { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Stage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 3 | { 4 | public class Stage 5 | { 6 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#stage 7 | //stages: 8 | //- stage: string # name of the stage (A-Z, a-z, 0-9, and underscore) 9 | // displayName: string # friendly name to display in the UI 10 | // dependsOn: string | [ string ] 11 | // condition: string 12 | // variables: # several syntaxes, see specific section 13 | // jobs: [ job | templateReference] 14 | public string stage { get; set; } 15 | public string displayName { get; set; } //This variable is not needed in actions 16 | //Add dependsOn processing for stages 17 | public string[] dependsOn { get; set; } 18 | public string condition { get; set; } 19 | //Variables is similar to triggers, this can be a simple list, or a more complex variable object 20 | public Dictionary variables { get; set; } 21 | //While not documented in official docs, stages can have pools 22 | public Pool pool { get; set; } 23 | public Job[] jobs { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Step.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 5 | { 6 | //https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#steps 7 | public class Step 8 | { 9 | //- script: dotnet build --configuration $(buildConfiguration) WebApplication1/WebApplication1.Service/WebApplication1.Service.csproj 10 | // displayName: dotnet build $(buildConfiguration) 11 | 12 | //steps: [script | bash | pwsh | powershell | checkout | task | templateReference] 13 | 14 | private string _script = null; 15 | public string script { 16 | get { 17 | return _script; 18 | } 19 | set { 20 | //Spaces on the beginning or end seem to be a problem for the YAML serialization 21 | if (!string.IsNullOrEmpty(value)) 22 | { 23 | value = value.Trim(); 24 | } 25 | _script = value; 26 | } 27 | } 28 | private string _bash = null; 29 | public string bash { 30 | get { 31 | return _bash; 32 | } 33 | set { 34 | //Spaces on the beginning or end seem to be a problem for the YAML serialization 35 | if (!string.IsNullOrEmpty(value)) 36 | { 37 | value = value.Trim(); 38 | } 39 | _bash = value; 40 | } 41 | } 42 | private string _pwsh = null; 43 | public string pwsh { 44 | get { 45 | return _pwsh; 46 | } 47 | set { 48 | //Spaces on the beginning or end seem to be a problem for the YAML serialization 49 | if (!string.IsNullOrEmpty(value)) 50 | { 51 | value = value.Trim(); 52 | } 53 | _pwsh = value; 54 | } 55 | } 56 | private string _powershell = null; 57 | public string powershell { 58 | get { 59 | return _powershell; 60 | } 61 | set { 62 | //Spaces on the beginning or end seem to be a problem for the YAML serialization 63 | if (!string.IsNullOrEmpty(value)) 64 | { 65 | value = value.Trim(); 66 | } 67 | _powershell = value; 68 | } 69 | } 70 | public string checkout { get; set; } 71 | public string task { get; set; } 72 | public string template { get; set; } 73 | public string publish { get; set; } 74 | public string download { get; set; } 75 | public string artifact { get; set; } 76 | public string patterns { get; set; } 77 | public string displayName { get; set; } 78 | public string name { get; set; } 79 | public string condition { get; set; } 80 | [DefaultValue(false)] 81 | public bool continueOnError { get; set; } = false; 82 | [DefaultValue(true)] 83 | public bool enabled { get; set; } = true; 84 | public int timeoutInMinutes { get; set; } 85 | public string workingDirectory { get; set; } 86 | public string failOnStderr { get; set; } 87 | public Target target { get; set; } 88 | public Dictionary inputs { get; set; } 89 | public Dictionary env { get; set; } 90 | public Dictionary parameters { get; set; } 91 | public string clean { get; set; } 92 | public string fetchDepth { get; set; } 93 | public string fetchTags { get; set; } 94 | public string lfs { get; set; } 95 | public string submodules { get; set; } 96 | public string path { get; set; } 97 | public string persistCredentials { get; set; } 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Strategy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 4 | { 5 | public class Strategy 6 | { 7 | //strategy: 8 | // parallel: # parallel strategy, see below 9 | // matrix: # matrix strategy, see below 10 | // maxParallel: number # maximum number of matrix jobs to run simultaneously 11 | 12 | //strategy: 13 | // matrix: 14 | // unit_test_linux: 15 | // imageName: 'ubuntu-16.04' 16 | // TYPE: 'unit' 17 | // cucumber: 18 | // imageName: 'ubuntu-16.04' 19 | // TYPE: 'cucumber' 20 | 21 | //strategy: 22 | // matrix: 23 | // linux: 24 | // imageName: "ubuntu-16.04" 25 | // mac: 26 | // imageName: "macos-10.13" 27 | // windows: 28 | // imageName: "vs2017-win2016" 29 | 30 | //Note that Parallel doesn't seem to currently have an equivalent in Actions 31 | public string parallel { get; set; } 32 | public Dictionary> matrix { get; set; } 33 | public string maxParallel { get; set; } 34 | 35 | public RunOnce runOnce { get; set; } 36 | public Canary canary { get; set; } 37 | public Rolling rolling { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Target.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Target 4 | { 5 | //target: 6 | // container: string # where this step will run; values are the container name or the word 'host' 7 | // commands: enum # whether to process all logging commands from this step; values are `any` (default) or `restricted` 8 | 9 | //TODO: There is currently no conversion path for target 10 | public string container { get; set; } 11 | public string commands { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Trigger.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //trigger: 4 | // batch: boolean # batch changes if true (the default); start a new build for every push if false 5 | // branches: 6 | // include: [ string ] # branch names which will trigger a build 7 | // exclude: [ string ] # branch names which will not 8 | // tags: 9 | // include: [ string ] # tag names which will trigger a build 10 | // exclude: [ string ] # tag names which will not 11 | // paths: 12 | // include: [ string ] # file paths which must match to trigger a build 13 | // exclude: [ string ] # file paths which will not trigger a build 14 | public class Trigger 15 | { 16 | public bool? batch { get; set; } = null; //Note: There is no batch property in actions 17 | public bool? autoCancel { get; set; } = null; //Note: There is no autoCancel property in actions 18 | public IncludeExclude branches { get; set; } 19 | public IncludeExclude tags { get; set; } 20 | public IncludeExclude paths { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Variable.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | //variables: 4 | //# a regular variable 5 | //- name: myvariable 6 | // value: myvalue 7 | //# a variable group 8 | //- group: myvariablegroup 9 | //# a reference to a variable template 10 | //- template: myvariabletemplate.yml 11 | public class Variable 12 | { 13 | public string name { get; set; } 14 | public string value { get; set; } 15 | //TODO: There is currently no conversion path for groups and templates 16 | public string group { get; set; } 17 | public string template { get; set; } 18 | public bool @readonly { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesModel/Workspace.cs: -------------------------------------------------------------------------------- 1 | namespace AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines 2 | { 3 | public class Workspace 4 | { 5 | //workspace: 6 | // clean: outputs | resources | all # what to clean up before the job runs 7 | 8 | //TODO: There is currently no conversion path for clean 9 | public string clean { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/AzurePipelinesToGitHubActionsConverter.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | true 9 | true 10 | MIT 11 | https://github.com/samsmithnz/AzurePipelinesToGitHubActionsConverter 12 | A conversion tool to migrate from Azure Pipelines YAML to GitHub Actions YAML 13 | yaml;serialization;github;github actions;azure devops;azure pipelines 14 | true 15 | snupkg 16 | true 17 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb 18 | 19 | 20 | 21 | true 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/ConversionResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Core 4 | { 5 | public class ConversionResponse 6 | { 7 | public string pipelinesYaml { get; set; } 8 | public string actionsYaml { get; set; } 9 | public List comments { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~P:AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines.Repositories._ref")] 9 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~P:AzurePipelinesToGitHubActionsConverter.Core.GitHubActions.Job._if")] 10 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~P:AzurePipelinesToGitHubActionsConverter.Core.GitHubActions.Step._if")] 11 | [assembly: SuppressMessage("Style", "IDE0057:Use range operator", Justification = "", Scope = "member", Target = "~M:AzurePipelinesToGitHubActionsConverter.Core.PipelinesToActionsConversion.ConditionsProcessing.SplitContents(System.String)~System.Collections.Generic.List{System.String}")] 12 | //https://stackoverflow.com/questions/11359652/suppressmessage-for-a-whole-namespace 13 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "namespaceanddescendants", Target = "~N:AzurePipelinesToGitHubActionsConverter.Core")] 14 | [assembly: SuppressMessage("Style", "IDE0066:Convert switch statement to expression", Justification = "", Scope = "member", Target = "~M:AzurePipelinesToGitHubActionsConverter.Core.PipelinesToActionsConversion.ConditionsProcessing.ProcessCondition(System.String,System.String)~System.String")] 15 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/PipelinesToActionsConversion/ConversionUtility.cs: -------------------------------------------------------------------------------- 1 | using GitHubActionsDotNet.Common; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace AzurePipelinesToGitHubActionsConverter.Core.PipelinesToActionsConversion 8 | { 9 | public static class ConversionUtility 10 | { 11 | // Some elements have a simple, same line string, we need to make into a list 12 | // for example "trigger:none", becomes "trigger:\n\r- none" 13 | // This is a lot simplier in JSON, as it's already only returning the none string. 14 | public const string ProcessNoneJsonElement = "[ none ]"; 15 | 16 | public static string GenerateSpaces(int number) 17 | { 18 | return new string(' ', number); 19 | } 20 | 21 | // https://stackoverflow.com/questions/20411812/count-the-spaces-at-start-of-a-string 22 | public static int CountSpacesBeforeText(string input) 23 | { 24 | input = input.Replace(Environment.NewLine, ""); 25 | return input.TakeWhile(char.IsWhiteSpace).Count(); 26 | } 27 | 28 | public static string CleanYamlBeforeDeserializationV2(string yaml) 29 | { 30 | string processedYaml = yaml; 31 | 32 | //test that the inputted yaml has a ":" in the yaml - this is present in even the simpliest yaml 33 | if (yaml.IndexOf(":") == -1) 34 | { 35 | throw new Exception("This appears to be invalid YAML"); 36 | } 37 | 38 | //Process conditional insertions/ variables 39 | if (processedYaml.IndexOf("{{#if") >= 0 || processedYaml.IndexOf("{{ #if") >= 0 || 40 | processedYaml.IndexOf("${{if") >= 0 || processedYaml.IndexOf("${{ if") >= 0) 41 | { 42 | StringBuilder sb = new StringBuilder(); 43 | int spacePrefixCount = 0; 44 | foreach (string line in processedYaml.Split(System.Environment.NewLine)) 45 | { 46 | if (line.IndexOf("{{#if") >= 0 || line.IndexOf("{{ #if") >= 0 || 47 | line.IndexOf("${{if") >= 0 || line.IndexOf("${{ if") >= 0) 48 | { 49 | //don't add line, we want to remove it, but track the spaces 50 | spacePrefixCount = ConversionUtility.CountSpacesBeforeText(line); 51 | } 52 | else if (line.IndexOf("{{/if") >= 0) //ending if 53 | { 54 | //don't add line, remove 55 | spacePrefixCount = 0; 56 | } 57 | else 58 | { 59 | //DANGER WILL ROBINSON - DANGER 60 | //This is meant for variables, but may affect much more than it should 61 | int currentLinespaceFrefixCount = ConversionUtility.CountSpacesBeforeText(line); 62 | if (spacePrefixCount > 0 && spacePrefixCount == (currentLinespaceFrefixCount - 2)) 63 | { 64 | //Correct the location. For example: 65 | // var1: value1 66 | //becomes: 67 | // var1: value1 68 | sb.Append(GenerateSpaces(spacePrefixCount)); 69 | sb.Append(line.Trim()); 70 | } 71 | else if (spacePrefixCount > 0 && spacePrefixCount > (currentLinespaceFrefixCount - 2)) 72 | { 73 | spacePrefixCount = 0; 74 | sb.Append(line); 75 | } 76 | else 77 | { 78 | sb.Append(line); 79 | } 80 | sb.Append(System.Environment.NewLine); 81 | } 82 | } 83 | processedYaml = sb.ToString(); 84 | } 85 | 86 | return processedYaml; 87 | 88 | } 89 | 90 | public static string ConvertMessageToYamlComment(string message) 91 | { 92 | //Append a comment to the message if one doesn't already exist 93 | if (!message.TrimStart().StartsWith("#")) 94 | { 95 | message = "#" + message; 96 | } 97 | return message; 98 | } 99 | 100 | //Add a steps parent, to allow the processing of an individual step to proceed 101 | public static string StepsPreProcessing(string input) 102 | { 103 | //If the step isn't wrapped in a "steps:" node, we need to add this, so we can process the step 104 | if (!input.Trim().StartsWith("steps:") && input.Trim().Length > 0) 105 | { 106 | //we need to add steps, before we do, we need to see if the task needs an indent 107 | string[] stepLines = input.Split(System.Environment.NewLine); 108 | if (stepLines.Length > 0) 109 | { 110 | int i = 0; 111 | //Search for the first non empty line 112 | while (string.IsNullOrEmpty(stepLines[i].Trim())) 113 | { 114 | i++; 115 | } 116 | if (stepLines[i].Trim().StartsWith("-")) 117 | { 118 | int indentLevel = stepLines[i].IndexOf("-"); 119 | indentLevel += 2; 120 | string buffer = ConversionUtility.GenerateSpaces(indentLevel); 121 | StringBuilder newInput = new StringBuilder(); 122 | foreach (string line in stepLines) 123 | { 124 | newInput.Append(buffer); 125 | newInput.Append(line); 126 | newInput.Append(System.Environment.NewLine); 127 | } 128 | input = newInput.ToString(); 129 | } 130 | 131 | input = "steps:" + System.Environment.NewLine + input; 132 | } 133 | } 134 | return input; 135 | } 136 | 137 | //Used by jobs and stages 138 | public static string GenerateJobName(AzurePipelines.Job job, int currentIndex) 139 | { 140 | //Get the job name 141 | string jobName = job.job; 142 | if (jobName == null && job.deployment != null) 143 | { 144 | jobName = job.deployment; 145 | } 146 | if (jobName == null && job.template != null) 147 | { 148 | jobName = "Template"; 149 | } 150 | if (string.IsNullOrEmpty(jobName)) 151 | { 152 | jobName = "job" + currentIndex.ToString(); 153 | } 154 | return jobName; 155 | } 156 | 157 | //Used when stages exist 158 | public static string GenerateCombinedStageJobName(string stageName, string jobName) 159 | { 160 | return stageName + "_Stage_" + jobName; 161 | } 162 | 163 | public static void WriteLine(string message, bool verbose) 164 | { 165 | if (verbose) 166 | { 167 | Debug.WriteLine(message); 168 | } 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/PipelinesToActionsConversion/SystemVariableProcessing.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Core.PipelinesToActionsConversion 4 | { 5 | public static class SystemVariableProcessing 6 | { 7 | 8 | public static string ProcessSystemVariables(string input) 9 | { 10 | //Conditions 11 | //Create a rule to look for the entire branch path (e.g. "refs/heads/feature-branch-1"). If this is the default branch, it will just be "" 12 | input = Replace(input, "variables['Build.SourceBranch']", "github.ref"); 13 | input = Replace(input, "variables['Build.ArtifactStagingDirectory']", "github.workspace"); 14 | input = Replace(input, "variables['Build.BuildId']", "github.run_id"); 15 | input = Replace(input, "variables['Build.BuildNumber']", "github.run_number"); 16 | input = Replace(input, "variables['Build.SourceBranch']", "github.ref"); 17 | input = Replace(input, "variables['Build.Repository.Name']", "github.repository"); 18 | // input = Replace(input, "variables['Build.SourceBranchName']", "github.ref"); 19 | input = Replace(input, "variables['Build.SourcesDirectory']", "github.workspace"); 20 | input = Replace(input, "variables['Build.StagingDirectory']", "github.workspace"); 21 | input = Replace(input, "variables['System.DefaultWorkingDirectory']", "github.workspace"); 22 | input = Replace(input, "variables['Agent.OS']", "runner.os"); 23 | //Create a rule to look for the branch name (e.g. "feature-branch-1" from "refs/heads/feature-branch-1"). 24 | //Note that only the left brackets need to exist, so that the other side of the equation still exists 25 | //input = Replace(input, "eq(variables['Build.SourceBranchName']", "endsWith(github.ref"); 26 | 27 | //System variables 28 | input = Replace(input, "$(Build.ArtifactStagingDirectory)", "${{ github.workspace }}"); 29 | input = Replace(input, "$(Build.BuildId)", "${{ github.run_id }}"); 30 | input = Replace(input, "$(Build.BuildNumber)", "${{ github.run_number }}"); 31 | input = Replace(input, "$(Build.SourceBranch)", "${{ github.ref }}"); 32 | input = Replace(input, "$(Build.Repository.Name)", "${{ github.repository }}"); 33 | // input = Replace(input, "$(Build.SourceBranchName)", "${{ github.ref }}"); 34 | input = Replace(input, "$(Build.SourcesDirectory)", "${{ github.workspace }}"); 35 | input = Replace(input, "$(Build.StagingDirectory)", "${{ github.workspace }}"); 36 | input = Replace(input, "$(System.DefaultWorkingDirectory)", "${{ github.workspace }}"); 37 | input = Replace(input, "$(Agent.OS)", "${{ runner.os }}"); 38 | 39 | return input; 40 | } 41 | 42 | //Reference: https://stackoverflow.com/questions/6275980/string-replace-ignoring-case 43 | private static string Replace(string input, string pattern, string replacement) 44 | { 45 | return Regex.Replace(input, Regex.Escape(pattern), replacement.Replace("$", "$$"), RegexOptions.IgnoreCase); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/Serialization/JSONSerialization.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text.Json; 3 | using YamlDotNet.Serialization; 4 | 5 | namespace AzurePipelinesToGitHubActionsConverter.Core.Serialization 6 | { 7 | public static class JsonSerialization 8 | { 9 | public static JsonElement DeserializeStringToJsonElement(string yaml) 10 | { 11 | //This looks inefficient, but helps to ensure the Yaml is clean and well formed 12 | //first we convert the yaml to a object 13 | StringReader sr = new StringReader(yaml); 14 | Deserializer deserializer = new Deserializer(); 15 | object yamlObject = deserializer.Deserialize(sr); 16 | //then convert the object back to yaml again to format the yaml 17 | string processedYaml = JsonSerializer.Serialize(yamlObject); 18 | //Finally we can return a JsonElement object from the processed Yaml. 19 | return JsonSerializer.Deserialize(processedYaml); 20 | } 21 | 22 | //From: https://stackoverflow.com/a/36125258/337421 23 | public static bool JsonCompare(this object obj, object another) 24 | { 25 | //Serialize two objects as strings 26 | string objJson = JsonSerializer.Serialize(obj); 27 | string anotherJson = JsonSerializer.Serialize(another); 28 | //Compare the strings 29 | return objJson == anotherJson; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Core/Serialization/YamlSerialization.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Core.Serialization 4 | { 5 | public static class YamlSerialization 6 | { 7 | //Read in a YAML file and convert it to a T object 8 | public static T DeserializeYaml(string yaml) 9 | { 10 | IDeserializer deserializer = new DeserializerBuilder().Build(); 11 | T yamlObject = deserializer.Deserialize(yaml); 12 | return yamlObject; 13 | } 14 | 15 | //Write a YAML file using the T object 16 | public static string SerializeYaml(T obj) 17 | { 18 | //Convert the object into a YAML document 19 | ISerializer serializer = new SerializerBuilder() 20 | .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults) //New as of YamlDotNet 8.0.0: https://github.com/aaubry/YamlDotNet/wiki/Serialization.Serializer#configuredefaultvalueshandlingdefaultvalueshandling. This will not show null properties, e.g. "app-name: " will not display when the value is null, as the value is nullable 21 | .Build(); 22 | string yaml = serializer.Serialize(obj); 23 | 24 | return yaml; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/AzurePipelinesToGitHubActionsConverter.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | all 10 | runtime; build; native; contentfiles; analyzers; buildtransitive 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | PreserveNewest 43 | 44 | 45 | PreserveNewest 46 | 47 | 48 | PreserveNewest 49 | 50 | 51 | PreserveNewest 52 | 53 | 54 | PreserveNewest 55 | 56 | 57 | PreserveNewest 58 | 59 | 60 | PreserveNewest 61 | 62 | 63 | PreserveNewest 64 | 65 | 66 | PreserveNewest 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | PreserveNewest 76 | 77 | 78 | PreserveNewest 79 | 80 | 81 | PreserveNewest 82 | 83 | 84 | PreserveNewest 85 | 86 | 87 | PreserveNewest 88 | 89 | 90 | PreserveNewest 91 | 92 | 93 | PreserveNewest 94 | 95 | 96 | PreserveNewest 97 | 98 | 99 | PreserveNewest 100 | 101 | 102 | PreserveNewest 103 | 104 | 105 | PreserveNewest 106 | 107 | 108 | PreserveNewest 109 | 110 | 111 | PreserveNewest 112 | 113 | 114 | PreserveNewest 115 | 116 | 117 | PreserveNewest 118 | 119 | 120 | PreserveNewest 121 | 122 | 123 | PreserveNewest 124 | 125 | 126 | PreserveNewest 127 | 128 | 129 | PreserveNewest 130 | 131 | 132 | PreserveNewest 133 | 134 | 135 | PreserveNewest 136 | 137 | 138 | PreserveNewest 139 | 140 | 141 | PreserveNewest 142 | 143 | 144 | PreserveNewest 145 | 146 | 147 | PreserveNewest 148 | 149 | 150 | PreserveNewest 151 | 152 | 153 | PreserveNewest 154 | 155 | 156 | PreserveNewest 157 | 158 | 159 | PreserveNewest 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/ContainerTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Tests 5 | { 6 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 7 | [TestClass] 8 | public class ContainerTests 9 | { 10 | [TestMethod] 11 | public void ContainerServicesTest() 12 | { 13 | //Arrange 14 | Conversion conversion = new Conversion(); 15 | string input = @" 16 | resources: 17 | containers: 18 | - container: my_container 19 | image: buildpack-deps:focal 20 | - container: nginx 21 | image: nginx 22 | 23 | 24 | pool: 25 | vmImage: 'ubuntu-20.04' 26 | 27 | container: my_container 28 | services: 29 | nginx: nginx 30 | 31 | steps: 32 | - script: | 33 | curl nginx 34 | displayName: Show that nginx is running"; 35 | 36 | //Act 37 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(input); 38 | 39 | //Assert 40 | string expected = @" 41 | #TODO: Container conversion not yet done, we need help!: https://github.com/samsmithnz/AzurePipelinesToGitHubActionsConverter/issues/39 42 | jobs: 43 | build: 44 | runs-on: ubuntu-20.04 45 | container: 46 | image: buildpack-deps:focal 47 | steps: 48 | - uses: actions/checkout@v2 49 | - name: Show that nginx is running 50 | run: curl nginx 51 | "; 52 | expected = UtilityTests.TrimNewLines(expected); 53 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 54 | 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/FolderOfYAMLFilesTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | namespace AzurePipelinesToGitHubActionsConverter.Tests 9 | { 10 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 11 | [TestClass] 12 | public class FolderOfYAMLFilesTests 13 | { 14 | 15 | [TestMethod] 16 | public void ProcessFolderOfYAMLTest() 17 | { 18 | //Arrange 19 | //Files downloaded from repo at: https://github.com/microsoft/azure-pipelines-yaml 20 | string sourceFolder = Path.Combine(Directory.GetCurrentDirectory(), "yamlFiles"); 21 | string[] files = Directory.GetFiles(sourceFolder); 22 | Conversion conversion = new Conversion(); 23 | List comments = new List(); 24 | 25 | //Act 26 | foreach (string path in files) //convert every YML file in the folder 27 | { 28 | try 29 | { 30 | //Open the file 31 | string yaml = File.ReadAllText(path); 32 | //Process the yaml string 33 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 34 | //Add any comments to a string list list 35 | comments.AddRange(gitHubOutput.comments); 36 | } 37 | catch (Exception ex) 38 | { 39 | Assert.AreEqual("", "File: " + Path.GetFileName(path) + ", Exception: " + ex.ToString()); 40 | } 41 | } 42 | 43 | //Assert 44 | //TODO: Solve roadblocks with the "FilesToIgnore" 45 | //Check if any errors were detected 46 | Assert.AreEqual(null, comments.FirstOrDefault(s => s.Contains("#Error:"))); 47 | //Check that the remaining comments equals what we expect 48 | Assert.AreEqual(33, comments.Count); 49 | } 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/GitHubSerializationTests.cs: -------------------------------------------------------------------------------- 1 | using GitHubActionsDotNet.Models; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using AzurePipelinesToGitHubActionsConverterCore = AzurePipelinesToGitHubActionsConverter.Core; 4 | 5 | namespace AzurePipelinesToGitHubActionsConverter.Tests 6 | { 7 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 8 | [TestClass] 9 | public class GitHubSerializationTests 10 | { 11 | 12 | [TestMethod] 13 | public void GitHubDeserializationTest() 14 | { 15 | //Arrange 16 | string yaml = @" 17 | on: 18 | push: 19 | branches: 20 | - main 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | name: Build 1 25 | runs-on: windows-latest 26 | steps: 27 | - uses: actions/checkout@v2 28 | - run: Write-Host ""Hello world!"" 29 | shell: powershell 30 | "; 31 | 32 | //Act 33 | GitHubActionsRoot gitHubAction = AzurePipelinesToGitHubActionsConverter.Core.Serialization.GitHubActionsSerialization.Deserialize(yaml); 34 | 35 | //Assert 36 | Assert.AreNotEqual(null, gitHubAction); 37 | Assert.AreEqual(null, gitHubAction.env); //environment variables are null 38 | 39 | //Test for messages and name 40 | Assert.AreEqual(0, gitHubAction.messages.Count); 41 | Assert.AreEqual(null, gitHubAction.name); 42 | 43 | //Test the trigger 44 | Assert.AreNotEqual(null, gitHubAction.on); 45 | Assert.AreEqual(null, gitHubAction.on.pull_request); 46 | Assert.AreNotEqual(null, gitHubAction.on.push); 47 | Assert.AreEqual(1, gitHubAction.on.push.branches.Length); 48 | Assert.AreEqual("main", gitHubAction.on.push.branches[0]); 49 | Assert.AreEqual(null, gitHubAction.on.push.branches_ignore); 50 | Assert.AreEqual(null, gitHubAction.on.push.paths); 51 | Assert.AreEqual(null, gitHubAction.on.push.paths_ignore); 52 | Assert.AreEqual(null, gitHubAction.on.push.tags); 53 | Assert.AreEqual(null, gitHubAction.on.push.tags_ignore); 54 | Assert.AreEqual(null, gitHubAction.on.schedule); 55 | 56 | //Test that jobs exist 57 | Assert.AreNotEqual(null, gitHubAction.jobs); 58 | Assert.AreEqual(1, gitHubAction.jobs.Count); 59 | Assert.AreEqual(true, gitHubAction.jobs.ContainsKey("build")); 60 | gitHubAction.jobs.TryGetValue("build", out Job gitHubJob); 61 | Assert.AreEqual(null, gitHubJob._if); 62 | Assert.AreEqual("Build 1", gitHubJob.name); 63 | Assert.AreEqual("windows-latest", gitHubJob.runs_on); 64 | 65 | //Test that steps exist 66 | Assert.AreNotEqual(null, gitHubJob.steps); 67 | Assert.AreEqual(2, gitHubJob.steps.Length); 68 | } 69 | 70 | 71 | [TestMethod] 72 | public void GitHubActionYamlToGenericObjectTest() 73 | { 74 | //Arrange 75 | string yaml = @" 76 | on: 77 | schedule: 78 | - cron: ""0 0 * * *"" 79 | "; 80 | 81 | //Act 82 | object yamlObject = AzurePipelinesToGitHubActionsConverterCore.Serialization.YamlSerialization.DeserializeYaml(yaml); 83 | 84 | //Assert 85 | Assert.AreNotEqual(null, yamlObject); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/PipelineTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System; 4 | 5 | namespace AzurePipelinesToGitHubActionsConverter.Tests 6 | { 7 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 8 | [TestClass] 9 | public class PipelineTests 10 | { 11 | [TestMethod] 12 | public void PipelineNameTest() 13 | { 14 | //Arrange 15 | Conversion conversion = new Conversion(); 16 | string yaml = "name: test ci pipelines"; 17 | 18 | //Act 19 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 20 | 21 | //Assert 22 | string expected = "name: test ci pipelines"; 23 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 24 | Assert.AreEqual(yaml, gitHubOutput.pipelinesYaml); 25 | } 26 | 27 | [TestMethod] 28 | public void PipelineInvalidStringTest() 29 | { 30 | //Arrange 31 | Conversion conversion = new Conversion(); 32 | string yaml = " "; 33 | 34 | //Act 35 | ConversionResponse gitHubOutput = null; 36 | try 37 | { 38 | gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 39 | } 40 | catch (Exception ex) 41 | { 42 | //Assert 43 | Assert.AreEqual("This appears to be invalid YAML", ex.Message); 44 | Assert.AreEqual(null, gitHubOutput); 45 | } 46 | } 47 | 48 | [TestMethod] 49 | public void PipelineNullStringTest() 50 | { 51 | //Arrange 52 | Conversion conversion = new Conversion(); 53 | string yaml = null; 54 | 55 | //Act 56 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 57 | 58 | //Assert 59 | string expected = ""; 60 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 61 | } 62 | 63 | [TestMethod] 64 | public void PipelineGarbageStringTest() 65 | { 66 | //Arrange 67 | Conversion conversion = new Conversion(); 68 | string yaml = "gdagfds"; 69 | 70 | //Act 71 | ConversionResponse gitHubOutput = null; 72 | try 73 | { 74 | gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 75 | } 76 | catch (Exception ex) 77 | { 78 | //Assert 79 | Assert.AreEqual("This appears to be invalid YAML", ex.Message); 80 | Assert.AreEqual(null, gitHubOutput); 81 | } 82 | 83 | } 84 | 85 | [TestMethod] 86 | public void PipelineSimpleStringTest() 87 | { 88 | //Arrange 89 | Conversion conversion = new Conversion(); 90 | string yaml = "pool: windows-latest"; 91 | 92 | //Act 93 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 94 | 95 | //Assert 96 | string expected = @" 97 | jobs: 98 | build: 99 | runs-on: windows-latest 100 | "; 101 | expected = UtilityTests.TrimNewLines(expected); 102 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 103 | } 104 | 105 | [TestMethod] 106 | public void PipelineWithInvalidStepTest() 107 | { 108 | //Arrange 109 | Conversion conversion = new Conversion(); 110 | string yaml = @" 111 | pool: 'windows-latest' 112 | steps: 113 | - task2: CmdLine@2 #This is purposely an invalid step 114 | "; 115 | 116 | //Act 117 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 118 | 119 | //Assert 120 | string expected = @" 121 | jobs: 122 | build: 123 | runs-on: windows-latest 124 | steps: 125 | - uses: actions/checkout@v2 126 | - run: ""This step is unknown and caused an exception: Property 'task2' not found on type 'AzurePipelinesToGitHubActionsConverter.Core.AzurePipelines.Step'."" 127 | "; 128 | //When this test runs on a Linux runner, the YAML converter returns a slightly different result 129 | expected = UtilityTests.TrimNewLines(expected); 130 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 131 | } 132 | 133 | [TestMethod] 134 | public void LineNumberPipelineTest() 135 | { 136 | //Arrange 137 | Conversion conversion = new Conversion(); 138 | string yaml = @" 139 | stages: 140 | - stage: Test 141 | jobs: 142 | - job: Code_Coverage 143 | displayName: 'Publish Code Coverage' 144 | pool: 145 | vmImage: 'ubuntu 16.04' 146 | steps: 147 | - task: PublishCodeCoverageResults@1 148 | displayName: 'Publish Azure Code Coverage' 149 | inputs: 150 | codeCoverageTool: 'JaCoCo' 151 | - task: Gulp@1 152 | - task: PublishCodeCoverageResults@1 153 | displayName: 'Publish Azure Code Coverage' 154 | inputs: 155 | codeCoverageTool: 'JaCoCo' 156 | - task: Gulp@1 157 | "; 158 | 159 | //Act 160 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 161 | 162 | //Assert 163 | //#Conversion messages (2): 164 | //#(line 18) Error: the step 'Gulp@1' does not have a conversion path yet 165 | //#(line 10) Error: the step 'PublishCodeCoverageResults@1' does not have a conversion path yet 166 | string expected = @" 167 | #Error (line 11): the step 'PublishCodeCoverageResults@1' does not have a conversion path yet 168 | #Error (line 19): the step 'Gulp@1' does not have a conversion path yet 169 | #Error (line 23): the step 'PublishCodeCoverageResults@1' does not have a conversion path yet 170 | #Error (line 31): the step 'Gulp@1' does not have a conversion path yet 171 | jobs: 172 | Test_Stage_Code_Coverage: 173 | name: Publish Code Coverage 174 | runs-on: ubuntu 16.04 175 | steps: 176 | - uses: actions/checkout@v2 177 | - # ""Error: the step 'PublishCodeCoverageResults@1' does not have a conversion path yet"" 178 | name: Publish Azure Code Coverage 179 | run: | 180 | echo ""Error: the step 'PublishCodeCoverageResults@1' does not have a conversion path yet"" 181 | #task: PublishCodeCoverageResults@1 182 | #displayName: Publish Azure Code Coverage 183 | #inputs: 184 | # codecoveragetool: JaCoCo 185 | - # ""Error: the step 'Gulp@1' does not have a conversion path yet"" 186 | run: | 187 | echo ""Error: the step 'Gulp@1' does not have a conversion path yet"" 188 | #task: Gulp@1 189 | - # ""Error: the step 'PublishCodeCoverageResults@1' does not have a conversion path yet"" 190 | name: Publish Azure Code Coverage 191 | run: | 192 | echo ""Error: the step 'PublishCodeCoverageResults@1' does not have a conversion path yet"" 193 | #task: PublishCodeCoverageResults@1 194 | #displayName: Publish Azure Code Coverage 195 | #inputs: 196 | # codecoveragetool: JaCoCo 197 | - # ""Error: the step 'Gulp@1' does not have a conversion path yet"" 198 | run: | 199 | echo ""Error: the step 'Gulp@1' does not have a conversion path yet"" 200 | #task: Gulp@1 201 | "; 202 | 203 | expected = UtilityTests.TrimNewLines(expected); 204 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 205 | 206 | } 207 | 208 | } 209 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/ResourcesTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Tests 5 | { 6 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 7 | [TestClass] 8 | public class ResourcesTests 9 | { 10 | 11 | [TestMethod] 12 | public void ResourcesContainersTest() 13 | { 14 | //Arrange 15 | Conversion conversion = new Conversion(); 16 | string yaml = @" 17 | pool: 18 | vmImage: 'ubuntu-16.04' 19 | 20 | strategy: 21 | matrix: 22 | DotNetCore22: 23 | containerImage: mcr.microsoft.com/dotnet/core/sdk:2.2 24 | DotNetCore22Nightly: 25 | containerImage: mcr.microsoft.com/dotnet/core-nightly/sdk:2.2 26 | 27 | container: $[ variables['containerImage'] ] 28 | 29 | resources: 30 | containers: 31 | - container: redis 32 | image: redis 33 | 34 | services: 35 | redis: redis 36 | 37 | variables: 38 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true 39 | 40 | steps: 41 | - task: DotNetCoreCLI@2 42 | displayName: Build 43 | inputs: 44 | command: build 45 | projects: '**/*.csproj' 46 | arguments: '--configuration release' 47 | 48 | - task: DotNetCoreCLI@2 49 | displayName: Test 50 | inputs: 51 | command: test 52 | projects: '**/*Tests.csproj' 53 | arguments: '--configuration release' 54 | env: 55 | CONNECTIONSTRINGS_REDIS: redis:6379 56 | 57 | - task: DotNetCoreCLI@2 58 | displayName: Publish 59 | inputs: 60 | command: publish 61 | projects: 'MyProject/MyProject.csproj' 62 | publishWebProjects: false 63 | zipAfterPublish: false 64 | arguments: '--configuration release' 65 | 66 | - task: PublishPipelineArtifact@0 67 | displayName: Store artifact 68 | inputs: 69 | artifactName: 'MyProject' 70 | targetPath: 'MyProject/bin/release/netcoreapp2.2/publish/' 71 | condition: and(succeeded(), endsWith(variables['Agent.JobName'], 'DotNetCore22')) 72 | "; 73 | 74 | //Act 75 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 76 | 77 | //Assert 78 | Assert.AreEqual(1, gitHubOutput.comments.Count); 79 | } 80 | 81 | [TestMethod] 82 | public void ResourcesContainersDetailTest() 83 | { 84 | //Arrange 85 | Conversion conversion = new Conversion(); 86 | string yaml = @" 87 | pool: 88 | vmImage: 'ubuntu-16.04' 89 | 90 | container: $[ 'mcr.microsoft.com/dotnet/core/sdk:2.2' ] 91 | 92 | resources: 93 | containers: 94 | - container: nginx 95 | image: nginx 96 | ports: 97 | - 8080:80 98 | env: 99 | NGINX_PORT: 80 100 | volumes: 101 | - mydockervolume:/data/dir 102 | - /data/dir 103 | - /src/dir:/dst/dir 104 | options: --hostname container-test --ip 192.168.0.1 105 | 106 | steps: 107 | - task: DotNetCoreCLI@2 108 | displayName: Build 109 | inputs: 110 | command: build 111 | projects: '**/*.csproj' 112 | arguments: '--configuration release' 113 | "; 114 | 115 | //Act 116 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 117 | 118 | //Assert 119 | Assert.AreEqual(1, gitHubOutput.comments.Count); 120 | } 121 | 122 | [TestMethod] 123 | public void ResourcesRepositoriesWithCheckoutTest() 124 | { 125 | //Arrange 126 | Conversion conversion = new Conversion(); 127 | string yaml = @" 128 | resources: 129 | repositories: 130 | - repository: MandMCounterRepo 131 | type: github 132 | endpoint: 'GitHub connection' 133 | name: SamSmithNZ/MandMCounter 134 | ref: myfeaturebranch 135 | jobs: 136 | - job: BuildAndTestMandMProject 137 | pool: 138 | vmImage: windows-latest 139 | steps: 140 | - checkout: MandMCounterRepo 141 | "; 142 | 143 | //Act 144 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 145 | 146 | //Assert 147 | string expected = @" 148 | jobs: 149 | BuildAndTestMandMProject: 150 | runs-on: windows-latest 151 | steps: 152 | - uses: actions/checkout@v2 153 | - uses: actions/checkout@v2 154 | with: 155 | repository: SamSmithNZ/MandMCounter 156 | ref: myfeaturebranch"; 157 | expected = UtilityTests.TrimNewLines(expected); 158 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 159 | } 160 | 161 | [TestMethod] 162 | public void ResourcesRepositoriesNoCheckoutTest() 163 | { 164 | //Arrange 165 | Conversion conversion = new Conversion(); 166 | string yaml = @" 167 | resources: 168 | repositories: 169 | - repository: secondaryRepo 170 | type: github 171 | connection: myGitHubConnection 172 | name: samsmithnz/mandmcounter 173 | ref: refs/heads/myfeaturebranch 174 | endpoint: github.com 175 | "; 176 | 177 | //Act 178 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 179 | 180 | //Assert 181 | string expected = @" 182 | "; 183 | expected = UtilityTests.TrimNewLines(expected); 184 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 185 | } 186 | 187 | [TestMethod] 188 | public void ResourcesRepositoriesMultipleWithCheckoutTest() 189 | { 190 | //Arrange 191 | Conversion conversion = new Conversion(); 192 | string yaml = @" 193 | resources: 194 | repositories: 195 | - repository: MandMCounterRepo 196 | type: github 197 | endpoint: 'GitHub connection' 198 | name: SamSmithNZ/MandMCounter 199 | ref: myfeaturebranch 200 | - repository: MandMCounterRepo2 201 | type: bitbucket 202 | endpoint: 'Bitbucket connection' 203 | name: SamSmithNZ/MandMCounter2 204 | ref: myfeaturebranch 205 | - repository: MandMCounterRepo3 206 | type: git 207 | name: MandMCounter3 208 | ref: myfeaturebranch 209 | jobs: 210 | - job: BuildAndTestMandMProject 211 | pool: 212 | vmImage: windows-latest 213 | steps: 214 | - checkout: MandMCounterRepo 215 | - checkout: MandMCounterRepo2 216 | - checkout: MandMCounterRepo3 217 | "; 218 | 219 | //Act 220 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 221 | 222 | //Assert 223 | string expected = @" 224 | #bitbucket repos don't currently have a conversion path in GitHub. This step was converted, but is unlikely to work. 225 | #Azure Repos don't currently have a conversion path in GitHub. This step was converted, but is unlikely to work. 226 | jobs: 227 | BuildAndTestMandMProject: 228 | runs-on: windows-latest 229 | steps: 230 | - uses: actions/checkout@v2 231 | - uses: actions/checkout@v2 232 | with: 233 | repository: SamSmithNZ/MandMCounter 234 | ref: myfeaturebranch 235 | - # bitbucket repos don't currently have a conversion path in GitHub. This step was converted, but is unlikely to work. 236 | uses: actions/checkout@v2 237 | with: 238 | repository: SamSmithNZ/MandMCounter2 239 | ref: myfeaturebranch 240 | - # Azure Repos don't currently have a conversion path in GitHub. This step was converted, but is unlikely to work. 241 | uses: actions/checkout@v2 242 | with: 243 | repository: MandMCounter3 244 | ref: myfeaturebranch"; 245 | expected = UtilityTests.TrimNewLines(expected); 246 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 247 | } 248 | 249 | [TestMethod] 250 | public void ResourcesPipelinesTest() 251 | { 252 | //Arrange 253 | Conversion conversion = new Conversion(); 254 | string yaml = @" 255 | resources: 256 | pipelines: 257 | - pipeline: SmartHotel 258 | project: DevOpsProject 259 | source: SmartHotel-CI 260 | branch: releases/M142 261 | version: 1.0 262 | trigger: 263 | autoCancel: true 264 | batch: true 265 | "; 266 | 267 | //Act 268 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(yaml); 269 | 270 | //Assert 271 | Assert.AreEqual(1, gitHubOutput.comments.Count); 272 | Assert.IsTrue(gitHubOutput.actionsYaml.IndexOf("Resource pipelines conversion not yet done") > -1); 273 | } 274 | 275 | } 276 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/StepsContainerTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Tests 5 | { 6 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 7 | [TestClass] 8 | public class StepsContainerTests 9 | { 10 | 11 | [TestMethod] 12 | public void Docker0BuildStepTest() 13 | { 14 | //Arrange 15 | Conversion conversion = new Conversion(); 16 | string yaml = @" 17 | - task: Docker@0 18 | displayName: 'Build an image' 19 | inputs: 20 | azureSubscription: '[Azure DevOps service connection]' 21 | azureContainerRegistry: '{""loginServer"":""[MyContainerRegistryName].azurecr.io"", ""id"" : ""/subscriptions/[MySubscriptionGuid]/resourceGroups/[MyResourceGroupName]/providers/Microsoft.ContainerRegistry/registries/[MyContainerRegistryName]""}' 22 | defaultContext: false 23 | context: ContainerPOC 24 | "; 25 | 26 | //Act 27 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 28 | 29 | //Assert 30 | string expected = @" 31 | - name: Build an image 32 | run: docker build --file Dockerfile ContainerPOC 33 | "; 34 | 35 | expected = UtilityTests.TrimNewLines(expected); 36 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 37 | } 38 | 39 | [TestMethod] 40 | public void Docker0PushStepTest() 41 | { 42 | //Arrange 43 | Conversion conversion = new Conversion(); 44 | string yaml = @" 45 | - task: Docker@0 46 | displayName: 'Push an image' 47 | inputs: 48 | azureSubscription: '[Azure DevOps service connection]' 49 | azureContainerRegistry: '{""loginServer"":""[MyContainerRegistryName].azurecr.io"", ""id"" : ""/subscriptions/[MySubscriptionGuid]/resourceGroups/[MyResourceGroupName]/providers/Microsoft.ContainerRegistry/registries/[MyContainerRegistryName]""}' 50 | action: 'Push an image' 51 | "; 52 | 53 | //Act 54 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 55 | 56 | //Assert 57 | string expected = @" 58 | - name: Push an image 59 | run: docker push --file Dockerfile [MyContainerRegistryName].azurecr.io 60 | "; 61 | 62 | expected = UtilityTests.TrimNewLines(expected); 63 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 64 | } 65 | 66 | [TestMethod] 67 | public void Docker1BuildStepTest() 68 | { 69 | //Arrange 70 | Conversion conversion = new Conversion(); 71 | string yaml = @" 72 | - task: Docker@1 73 | displayName: 'Build an image' 74 | inputs: 75 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 76 | azureContainerRegistry: '$(ACR.FullName)' 77 | command: build 78 | dockerFile: '**/Dockerfile' 79 | useDefaultContext: false 80 | buildContext: ContainerPOC 81 | 82 | "; 83 | 84 | //Act 85 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 86 | 87 | //Assert 88 | string expected = @" 89 | - name: Build an image 90 | run: docker build --file **/Dockerfile ContainerPOC 91 | "; 92 | 93 | expected = UtilityTests.TrimNewLines(expected); 94 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 95 | } 96 | 97 | [TestMethod] 98 | public void Docker1PushStepTest() 99 | { 100 | //Arrange 101 | Conversion conversion = new Conversion(); 102 | string yaml = @" 103 | - task: Docker@1 104 | displayName: 'Push an image' 105 | inputs: 106 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 107 | azureContainerRegistry: '$(ACR.FullName)' 108 | imageName: '$(ACR.ImageName)' 109 | command: push 110 | "; 111 | 112 | //Act 113 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 114 | 115 | //Assert 116 | string expected = @" 117 | - name: Push an image 118 | run: docker push --file Dockerfile ${{ env.ACR.FullName }} ${{ env.ACR.ImageName }} 119 | "; 120 | 121 | expected = UtilityTests.TrimNewLines(expected); 122 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 123 | } 124 | 125 | [TestMethod] 126 | public void Docker2BuildStepTest() 127 | { 128 | //Arrange 129 | Conversion conversion = new Conversion(); 130 | string yaml = @" 131 | - task: Docker@2 132 | displayName: Build 133 | inputs: 134 | command: build 135 | repository: contosoRepository 136 | Dockerfile: app/Dockerfile 137 | arguments: --secret id=mysecret,src=mysecret.txt 138 | "; 139 | 140 | //Act 141 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 142 | 143 | //Assert 144 | string expected = @" 145 | - name: Build 146 | run: docker build --file app/Dockerfile contosoRepository --secret id=mysecret,src=mysecret.txt 147 | "; 148 | 149 | expected = UtilityTests.TrimNewLines(expected); 150 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 151 | } 152 | 153 | [TestMethod] 154 | public void Docker2PushStepTest() 155 | { 156 | //Arrange 157 | Conversion conversion = new Conversion(); 158 | string yaml = @" 159 | - task: Docker@2 160 | displayName: Push image 161 | inputs: 162 | containerRegistry: | 163 | $(dockerHub) 164 | repository: $(imageName) 165 | command: push 166 | tags: | 167 | test1 168 | test2 169 | "; 170 | 171 | //Act 172 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 173 | 174 | //Assert 175 | string expected = @" 176 | - name: Push image 177 | run: docker push --file Dockerfile ${{ env.dockerHub }} ${{ env.imageName }} --tags test1,test2 178 | "; 179 | 180 | expected = UtilityTests.TrimNewLines(expected); 181 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 182 | } 183 | 184 | [TestMethod] 185 | public void Docker2BuildAndPushStepTest() 186 | { 187 | //Arrange 188 | Conversion conversion = new Conversion(); 189 | string yaml = @" 190 | - task: Docker@2 191 | displayName: Build and Push 192 | inputs: 193 | command: buildAndPush 194 | containerRegistry: dockerRegistryServiceConnection1 195 | repository: contosoRepository 196 | tags: | 197 | tag1 198 | tag2 199 | "; 200 | 201 | //Act 202 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 203 | 204 | //Assert 205 | string expected = @" 206 | - name: Build and Push 207 | run: | 208 | docker build --file Dockerfile dockerRegistryServiceConnection1 contosoRepository --tags tag1,tag2 209 | docker push --file Dockerfile dockerRegistryServiceConnection1 contosoRepository --tags tag1,tag2 210 | "; 211 | 212 | expected = UtilityTests.TrimNewLines(expected); 213 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 214 | } 215 | 216 | [TestMethod] 217 | public void Docker2LoginStepTest() 218 | { 219 | //Arrange 220 | Conversion conversion = new Conversion(); 221 | string yaml = @" 222 | - task: Docker@2 223 | displayName: Login to ACR 224 | inputs: 225 | command: login 226 | containerRegistry: dockerRegistryServiceConnection1 227 | "; 228 | 229 | //Act 230 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 231 | 232 | //Assert 233 | string expected = @" 234 | - name: Login to ACR 235 | run: docker login dockerRegistryServiceConnection1 236 | "; 237 | 238 | expected = UtilityTests.TrimNewLines(expected); 239 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 240 | } 241 | 242 | [TestMethod] 243 | public void Docker2LogoutStepTest() 244 | { 245 | //Arrange 246 | Conversion conversion = new Conversion(); 247 | string yaml = @" 248 | - task: Docker@2 249 | displayName: Logout of ACR 250 | inputs: 251 | command: logout 252 | containerRegistry: dockerRegistryServiceConnection1 253 | "; 254 | 255 | //Act 256 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 257 | 258 | //Assert 259 | string expected = @" 260 | - name: Logout of ACR 261 | run: docker logout dockerRegistryServiceConnection1 262 | "; 263 | 264 | expected = UtilityTests.TrimNewLines(expected); 265 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 266 | } 267 | 268 | } 269 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/StepsUnfinishedTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace AzurePipelinesToGitHubActionsConverter.Tests 4 | { 5 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 6 | [TestClass] 7 | public class StepsUnfinishedTests 8 | { 9 | 10 | // [TestMethod] 11 | // public void InvalidStepIndividualStepTest() 12 | // { 13 | // //Arrange 14 | // Conversion conversion = new Conversion(); 15 | // string yaml = @" 16 | // - task: Gulp@1 17 | //"; 18 | 19 | // //Act 20 | // ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineTaskToGitHubActionTask(yaml); 21 | 22 | // //Assert 23 | // string expected = @" 24 | //- # ""Note: Error! The GULP@1 step does not have a conversion path yet, but it's on our radar. Please consider contributing! https://github.com/samsmithnz/AzurePipelinesToGitHubActionsConverter/issues/219"" 25 | // run: ""echo \""Note: Error! The GULP@1 step does not have a conversion path yet, but it's on our radar. Please consider contributing! https://github.com/samsmithnz/AzurePipelinesToGitHubActionsConverter/issues/219 #task: Gulp@1\"""" 26 | //"; 27 | // expected = UtilityTests.TrimNewLines(expected); 28 | // Assert.AreEqual(expected, gitHubOutput.actionsYaml); 29 | // } 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/TemplateTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Tests 5 | { 6 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 7 | [TestClass] 8 | public class TemplateTests 9 | { 10 | [TestMethod] 11 | public void TemplatesCallingYamlTest() 12 | { 13 | //Arrange 14 | string input = @" 15 | jobs: 16 | - template: azure-pipelines-build-template.yml 17 | parameters: 18 | buildConfiguration: 'Release' 19 | buildPlatform: 'Any CPU' 20 | vmImage: windows-latest"; 21 | Conversion conversion = new Conversion(); 22 | 23 | //Act 24 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(input); 25 | 26 | //Assert 27 | string expected = @" 28 | #Note: Azure DevOps template does not have an equivalent in GitHub Actions yet 29 | jobs: 30 | job_1_template: 31 | # 'Note: Azure DevOps template does not have an equivalent in GitHub Actions yet' 32 | steps: 33 | - uses: actions/checkout@v2"; 34 | expected = UtilityTests.TrimNewLines(expected); 35 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 36 | 37 | } 38 | 39 | [TestMethod] 40 | public void TemplatesChildYAMLWithParametersTest() 41 | { 42 | //Arrange 43 | string input = @" 44 | parameters: 45 | buildConfiguration: 'Release' 46 | buildPlatform: 'Any CPU' 47 | 48 | jobs: 49 | - job: Build 50 | displayName: 'Build job' 51 | pool: 52 | vmImage: windows-latest 53 | steps: 54 | - task: PowerShell@2 55 | displayName: 'Test' 56 | inputs: 57 | targetType: inline 58 | script: | 59 | Write-Host ""Hello world ${{parameters.buildConfiguration}} ${{parameters.buildPlatform}}"""; 60 | Conversion conversion = new Conversion(); 61 | 62 | //Act 63 | ConversionResponse gitHubOutput = conversion.ConvertAzurePipelineToGitHubAction(input); 64 | 65 | //Assert 66 | string expected = @" 67 | env: 68 | buildConfiguration: Release 69 | buildPlatform: Any CPU 70 | jobs: 71 | Build: 72 | name: Build job 73 | runs-on: windows-latest 74 | steps: 75 | - uses: actions/checkout@v2 76 | - name: Test 77 | run: Write-Host ""Hello world ${{ env.buildConfiguration }} ${{ env.buildPlatform }}"" 78 | shell: powershell"; 79 | expected = UtilityTests.TrimNewLines(expected); 80 | Assert.AreEqual(expected, gitHubOutput.actionsYaml); 81 | 82 | } 83 | 84 | } 85 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/UtilityTests.cs: -------------------------------------------------------------------------------- 1 | using AzurePipelinesToGitHubActionsConverter.Core.PipelinesToActionsConversion; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace AzurePipelinesToGitHubActionsConverter.Tests 5 | { 6 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 7 | [TestClass] 8 | public class UtilityTests 9 | { 10 | [TestMethod] 11 | public void GenerateSpacesTest() 12 | { 13 | //Arrange 14 | int number0 = 0; 15 | int number1 = 1; 16 | int number4 = 4; 17 | int number9 = 9; 18 | 19 | //Act 20 | string results0 = ConversionUtility.GenerateSpaces(number0); 21 | string results1 = ConversionUtility.GenerateSpaces(number1); 22 | string results4 = ConversionUtility.GenerateSpaces(number4); 23 | string results9 = ConversionUtility.GenerateSpaces(number9); 24 | 25 | //Assert 26 | Assert.AreEqual("", results0); 27 | Assert.AreEqual(" ", results1); 28 | Assert.AreEqual(" ", results4); 29 | Assert.AreEqual(" ", results9); 30 | } 31 | 32 | public static string TrimNewLines(string input) 33 | { 34 | //Trim off any leading or trailing new lines 35 | input = input.TrimStart('\r', '\n'); 36 | input = input.TrimEnd('\r', '\n'); 37 | 38 | return input; 39 | } 40 | 41 | public static string DebugNewLineCharacters(string input) 42 | { 43 | input = input.Replace("\r", "xxx"); 44 | input = input.Replace("\n", "000"); 45 | return input; 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/filesNotCurrentlyWorking/deploy-to-existing-kubernetes-cluster-devspaces.yml: -------------------------------------------------------------------------------- 1 | # Deploy to Kubernetes - Review app with Azure DevSpaces 2 | # Build and push image to Azure Container Registry; Deploy to Azure Kuberentes Services and setup Review App with Azure DevSpaces 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | 13 | # Container registry service connection established during pipeline creation 14 | dockerRegistryServiceConnection: '{{ containerRegistryConnection.Id }}' 15 | imageRepository: '{{#toAlphaNumericString imageRepository 50}}{{/toAlphaNumericString}}' 16 | containerRegistry: '{{ containerRegistryConnection.Authorization.Parameters.loginServer }}' 17 | dockerfilePath: '**/Dockerfile' 18 | tag: '$(Build.BuildId)' 19 | imagePullSecret: '{{#toAlphaNumericString containerRegistryConnection.Name 50}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}-auth' 20 | 21 | # Agent VM image name 22 | vmImageName: 'ubuntu-latest' 23 | 24 | # Azure Service connection 25 | azureConnection: '{{ azureServiceConnection.Id }}' 26 | 27 | {{#if reviewApp}} 28 | # Name of the new namespace being created to deploy the PR changes. 29 | k8sNamespaceForPR: '$(system.pullRequest.sourceBranch)' 30 | {{/if}} 31 | 32 | stages: 33 | - stage: Build 34 | displayName: Build stage 35 | jobs: 36 | - job: Build 37 | displayName: Build 38 | pool: 39 | vmImage: $(vmImageName) 40 | steps: 41 | - task: Docker@2 42 | displayName: Build and push an image to container registry 43 | inputs: 44 | command: buildAndPush 45 | repository: $(imageRepository) 46 | dockerfile: $(dockerfilePath) 47 | containerRegistry: $(dockerRegistryServiceConnection) 48 | tags: | 49 | $(tag) 50 | 51 | - upload: charts 52 | artifact: charts 53 | 54 | - stage: Deploy 55 | displayName: Deploy stage 56 | dependsOn: Build 57 | 58 | jobs: 59 | - deployment: Deploy 60 | {{#if reviewApp}} 61 | condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/'))) 62 | {{/if}} 63 | displayName: Deploy 64 | pool: 65 | vmImage: $(vmImageName) 66 | environment: '{{ k8sResource.EnvironmentReference.Name }}.{{ k8sResource.Name }}' 67 | strategy: 68 | runOnce: 69 | deploy: 70 | steps: 71 | - task: KubernetesManifest@0 72 | displayName: Create imagePullSecret 73 | inputs: 74 | action: createSecret 75 | secretName: $(imagePullSecret) 76 | dockerRegistryEndpoint: $(dockerRegistryServiceConnection) 77 | 78 | - task: AzureCLI@2 79 | displayName: get host suffix 80 | inputs: 81 | scriptType: pscore 82 | scriptLocation: inlineScript 83 | azureSubscription: $(azureConnection) 84 | inlineScript: | 85 | $clusterId="{{ k8sConnection.Data.clusterId }}" 86 | $resourceGroupName=$(echo "$clusterId" | cut -d '/' -f5 ) 87 | $clusterName=$(echo "$clusterId" | cut -d '/' -f9 ) 88 | 89 | az aks use-dev-spaces -n $clusterName -g $resourceGroupName -s default -y 90 | $hostSuffix=$(azds show-context -o json | ConvertFrom-Json).controller.hostSuffix 91 | echo "##vso[task.setvariable variable=HostSuffix]$hostSuffix" 92 | 93 | - task: KubernetesManifest@0 94 | displayName: Bake manifests 95 | name: bake 96 | inputs: 97 | action: bake 98 | helmChart: $(Pipeline.Workspace)/charts/devspaces-v0.0.1.tgz 99 | overrides: | 100 | image.repository:$(containerRegistry)/$(imageRepository) 101 | service.port:{{ servicePort }} 102 | ingress.enabled:true 103 | ingress.hostname:app.$(HostSuffix) 104 | 105 | - task: KubernetesManifest@0 106 | displayName: Deploy to Kubernetes cluster 107 | inputs: 108 | action: deploy 109 | manifests: | 110 | $(bake.manifestsBundle) 111 | imagePullSecrets: | 112 | $(imagePullSecret) 113 | containers: | 114 | $(containerRegistry)/$(imageRepository):$(tag) 115 | 116 | {{#if reviewApp}} 117 | - deployment: DeployPullRequest 118 | displayName: Deploy Pull request 119 | condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/')) 120 | pool: 121 | vmImage: $(vmImageName) 122 | 123 | environment: '{{ k8sResource.EnvironmentReference.Name }}.$(k8sNamespaceForPR)' 124 | strategy: 125 | runOnce: 126 | deploy: 127 | steps: 128 | - reviewApp: {{ k8sResource.Name }} 129 | 130 | - task: Kubernetes@1 131 | displayName: 'Create a new namespace for the pull request' 132 | inputs: 133 | command: apply 134 | useConfigurationFile: true 135 | inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)", "labels": { "azds.io/space": "true", "azds.io/parent-space": "{{ k8sResource.Name }}" }}}' 136 | 137 | - task: KubernetesManifest@0 138 | displayName: Create imagePullSecret 139 | inputs: 140 | action: createSecret 141 | secretName: $(imagePullSecret) 142 | namespace: $(k8sNamespaceForPR) 143 | dockerRegistryEndpoint: $(dockerRegistryServiceConnection) 144 | 145 | - task: AzureCLI@2 146 | displayName: get host suffix 147 | inputs: 148 | scriptType: pscore 149 | scriptLocation: inlineScript 150 | azureSubscription: $(azureConnection) 151 | inlineScript: | 152 | $clusterId="{{ k8sConnection.Data.clusterId }}" 153 | $resourceGroupName=$(echo "$clusterId" | cut -d '/' -f5 ) 154 | $clusterName=$(echo "$clusterId" | cut -d '/' -f9 ) 155 | 156 | az aks use-dev-spaces -n $clusterName -g $resourceGroupName -s default -y 157 | $hostSuffix=$(azds show-context -o json | ConvertFrom-Json).controller.hostSuffix 158 | echo "##vso[task.setvariable variable=HostSuffix]$hostSuffix" 159 | 160 | - task: KubernetesManifest@0 161 | displayName: Bake manifests 162 | name: bake 163 | inputs: 164 | action: bake 165 | helmChart: $(Pipeline.Workspace)/charts/devspaces-v0.0.1.tgz 166 | overrides: | 167 | image.repository:$(containerRegistry)/$(imageRepository) 168 | service.port:{{ servicePort }} 169 | ingress.enabled:true 170 | ingress.hostname:$(k8sNamespaceForPR).s.app.$(HostSuffix) 171 | 172 | - task: KubernetesManifest@0 173 | displayName: Deploy to the new namespace in the Kubernetes cluster 174 | inputs: 175 | action: deploy 176 | namespace: $(k8sNamespaceForPR) 177 | manifests: | 178 | $(bake.manifestsBundle) 179 | imagePullSecrets: | 180 | $(imagePullSecret) 181 | containers: | 182 | $(containerRegistry)/$(imageRepository):$(tag) 183 | 184 | - script: | 185 | message="Deployment to your Review App succeeded.

You can navigate to http://$(k8sNamespaceForPR).s.app.$(HostSuffix) to test your changes" 186 | echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message" 187 | {{/if}} -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/filesNotCurrentlyWorking/deploy-to-existing-kubernetes-cluster.yml: -------------------------------------------------------------------------------- 1 | # Deploy to Azure Kubernetes Service 2 | # Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | 13 | # Container registry service connection established during pipeline creation 14 | dockerRegistryServiceConnection: '{{ containerRegistryConnection.Id }}' 15 | imageRepository: '{{#toAlphaNumericString imageRepository 50}}{{/toAlphaNumericString}}' 16 | containerRegistry: '{{ containerRegistryConnection.Authorization.Parameters.loginServer }}' 17 | dockerfilePath: '**/Dockerfile' 18 | tag: '$(Build.BuildId)' 19 | imagePullSecret: '{{#toAlphaNumericString containerRegistryConnection.Name 50}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}-auth' 20 | 21 | # Agent VM image name 22 | vmImageName: 'ubuntu-latest' 23 | 24 | {{#if reviewApp}} 25 | # Name of the new namespace being created to deploy the PR changes. 26 | k8sNamespaceForPR: '$(system.pullRequest.sourceBranch)' 27 | {{/if}} 28 | 29 | stages: 30 | - stage: Build 31 | displayName: Build stage 32 | jobs: 33 | - job: Build 34 | displayName: Build 35 | pool: 36 | vmImage: $(vmImageName) 37 | steps: 38 | - task: Docker@2 39 | displayName: Build and push an image to container registry 40 | inputs: 41 | command: buildAndPush 42 | repository: $(imageRepository) 43 | dockerfile: $(dockerfilePath) 44 | containerRegistry: $(dockerRegistryServiceConnection) 45 | tags: | 46 | $(tag) 47 | 48 | - upload: manifests 49 | artifact: manifests 50 | 51 | - stage: Deploy 52 | displayName: Deploy stage 53 | dependsOn: Build 54 | 55 | jobs: 56 | - deployment: Deploy 57 | {{#if reviewApp}} 58 | condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/'))) 59 | {{/if}} 60 | displayName: Deploy 61 | pool: 62 | vmImage: $(vmImageName) 63 | environment: '{{ k8sResource.EnvironmentReference.Name }}.{{ k8sResource.Name }}' 64 | strategy: 65 | runOnce: 66 | deploy: 67 | steps: 68 | - task: KubernetesManifest@0 69 | displayName: Create imagePullSecret 70 | inputs: 71 | action: createSecret 72 | secretName: $(imagePullSecret) 73 | dockerRegistryEndpoint: $(dockerRegistryServiceConnection) 74 | 75 | - task: KubernetesManifest@0 76 | displayName: Deploy to Kubernetes cluster 77 | inputs: 78 | action: deploy 79 | manifests: | 80 | $(Pipeline.Workspace)/manifests/deployment.yml 81 | $(Pipeline.Workspace)/manifests/service.yml 82 | imagePullSecrets: | 83 | $(imagePullSecret) 84 | containers: | 85 | $(containerRegistry)/$(imageRepository):$(tag) 86 | 87 | {{#if reviewApp}} 88 | - deployment: DeployPullRequest 89 | displayName: Deploy Pull request 90 | condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/')) 91 | pool: 92 | vmImage: $(vmImageName) 93 | 94 | environment: '{{ k8sResource.EnvironmentReference.Name }}.$(k8sNamespaceForPR)' 95 | strategy: 96 | runOnce: 97 | deploy: 98 | steps: 99 | - reviewApp: {{ k8sResource.Name }} 100 | 101 | - task: Kubernetes@1 102 | displayName: 'Create a new namespace for the pull request' 103 | inputs: 104 | command: apply 105 | useConfigurationFile: true 106 | inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)" }}' 107 | 108 | - task: KubernetesManifest@0 109 | displayName: Create imagePullSecret 110 | inputs: 111 | action: createSecret 112 | secretName: $(imagePullSecret) 113 | namespace: $(k8sNamespaceForPR) 114 | dockerRegistryEndpoint: $(dockerRegistryServiceConnection) 115 | 116 | - task: KubernetesManifest@0 117 | displayName: Deploy to the new namespace in the Kubernetes cluster 118 | inputs: 119 | action: deploy 120 | namespace: $(k8sNamespaceForPR) 121 | manifests: | 122 | $(Pipeline.Workspace)/manifests/deployment.yml 123 | $(Pipeline.Workspace)/manifests/service.yml 124 | imagePullSecrets: | 125 | $(imagePullSecret) 126 | containers: | 127 | $(containerRegistry)/$(imageRepository):$(tag) 128 | 129 | - task: Kubernetes@1 130 | name: get 131 | displayName: 'Get services in the new namespace' 132 | continueOnError: true 133 | inputs: 134 | command: get 135 | namespace: $(k8sNamespaceForPR) 136 | arguments: svc 137 | outputFormat: jsonpath='http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}' 138 | 139 | # Getting the IP of the deployed service and writing it to a variable for posing comment 140 | - script: | 141 | url="$(get.KubectlOutput)" 142 | message="Your review app has been deployed" 143 | if [ ! -z "$url" -a "$url" != "http://:" ] 144 | then 145 | message="${message} and is available at $url.

[Learn More](https://aka.ms/testwithreviewapps) about how to test and provide feedback for the app." 146 | fi 147 | echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message" 148 | {{/if}} 149 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/filesNotCurrentlyWorking/docker-container-to-aks.yml: -------------------------------------------------------------------------------- 1 | # Docker image, Azure Container Registry, and Azure Kubernetes Service 2 | # Build a Docker image, push it to an Azure Container Registry, and deploy it to Azure Kubernetes Service. 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # ======================================================================== 13 | # Mandatory variables 14 | # ======================================================================== 15 | 16 | # Update Azure.ResourceGroupName value with Azure resource group name. 17 | Azure.ResourceGroupName: '{{#toAlphaNumericString repositoryName 50}}{{/toAlphaNumericString}}' 18 | 19 | # Update Azure.ServiceConnectionId value with AzureRm service endpoint. 20 | Azure.ServiceConnectionId: '{{ azureServiceConnectionId }}' 21 | 22 | # Update Azure.Location value with Azure Location. 23 | Azure.Location: 'eastus' 24 | 25 | # Update ACR.Name value with ACR name. Please note ACR names should be all lower-case and alphanumeric only. 26 | ACR.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 27 | 28 | # Update AKS.ClusterName value Azure kubernetes cluster name. 29 | AKS.ClusterName: '{{#toAlphaNumericString repositoryName 32}}{{/toAlphaNumericString}}' 30 | 31 | # Docker Container port 32 | Container.Port: 5000 33 | 34 | # ======================================================================== 35 | # Optional variables 36 | # ======================================================================== 37 | 38 | ACR.RepositoryName: '$(ACR.Name)' 39 | ACR.ImageName: '$(ACR.Name):$(Build.BuildId)' 40 | ACR.FullName: '$(ACR.Name).azurecr.io' 41 | ACR.Sku: 'Standard' 42 | AKS.KubeDeploymentYaml: '$(System.DefaultWorkingDirectory)/KubeDeployment.yml' # Update AKS.KubeDeploymentYaml if you want to use deployment file from repo instead of generated file. 43 | AKS.DeploymentPort: '$(Container.Port)' 44 | Azure.CreateResources: 'true' # Update Azure.CreateResources to false if you have already created resources like resource group, azure container registry and azure kubernetes cluster. 45 | System.Debug: 'false' 46 | 47 | jobs: 48 | 49 | - job: CreateResources 50 | displayName: Create resources 51 | condition: and(succeeded(), eq(variables['Azure.CreateResources'], 'true')) 52 | 53 | pool: 54 | vmImage: 'ubuntu-latest' 55 | 56 | steps: 57 | - task: AzureResourceGroupDeployment@2 58 | displayName: 'Azure Deployment:Create ACR and AKS' 59 | inputs: 60 | azureSubscription: '$(Azure.ServiceConnectionId)' 61 | resourceGroupName: '$(Azure.ResourceGroupName)' 62 | location: '$(Azure.Location)' 63 | templateLocation: 'URL of the file' 64 | addSpnToEnvironment: true 65 | csmFileLink: 'https://raw.githubusercontent.com/Microsoft/azure-pipelines-yaml/master/templates/resources/arm/aks.json' 66 | overrideParameters: '-registryName "$(ACR.Name)" -registryLocation "$(Azure.Location)" -servicePrincipalId $servicePrincipalId -servicePrincipalKey $servicePrincipalKey -clusterName "$(AKS.ClusterName)" -clusterLocation "$(Azure.Location)"' 67 | 68 | - job: BuildImage 69 | displayName: Build 70 | dependsOn: CreateResources 71 | condition: or(succeeded(), ne(variables['Azure.CreateResources'], 'true')) 72 | 73 | pool: 74 | vmImage: 'ubuntu-latest' 75 | 76 | steps: 77 | - task: Docker@1 78 | displayName: 'Build an image' 79 | inputs: 80 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 81 | azureContainerRegistry: '$(ACR.FullName)' 82 | imageName: '$(ACR.ImageName)' 83 | command: build 84 | dockerFile: '**/Dockerfile' 85 | 86 | - task: Docker@1 87 | displayName: 'Push an image' 88 | inputs: 89 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 90 | azureContainerRegistry: '$(ACR.FullName)' 91 | imageName: '$(ACR.ImageName)' 92 | command: push 93 | 94 | - job: DeployApp 95 | displayName: Deploy 96 | dependsOn: BuildImage 97 | condition: succeeded() 98 | 99 | pool: 100 | vmImage: 'ubuntu-latest' 101 | 102 | steps: 103 | - bash: | 104 | if [ -f $(AKS.KubeDeploymentYaml) ]; then 105 | echo "##vso[task.setvariable variable=AKS.KubeDeploymentYamlExists;]true" 106 | else 107 | echo "##vso[task.setvariable variable=AKS.KubeDeploymentYamlExists;]false" 108 | fi 109 | displayName: 'Check kubernetes deployment yaml exists' 110 | 111 | - bash: | 112 | echo "apiVersion : apps/v1beta1 113 | kind: Deployment 114 | metadata: 115 | name: $(ACR.RepositoryName) 116 | spec: 117 | replicas: 1 118 | template: 119 | metadata: 120 | labels: 121 | app: $(ACR.RepositoryName) 122 | spec: 123 | containers: 124 | - name: $(ACR.RepositoryName) 125 | image: $(ACR.FullName)/$(ACR.ImageName) 126 | ports: 127 | - containerPort: $(AKS.DeploymentPort) 128 | --- 129 | apiVersion: v1 130 | kind: Service 131 | metadata: 132 | name: $(ACR.RepositoryName) 133 | spec: 134 | type: LoadBalancer 135 | ports: 136 | - port: $(AKS.DeploymentPort) 137 | selector: 138 | app: $(ACR.RepositoryName)" > $(AKS.KubeDeploymentYaml) 139 | displayName: 'Generate kubernetes deployment yaml' 140 | condition: and(succeeded(), eq(variables['AKS.KubeDeploymentYamlExists'], 'False')) 141 | 142 | - task: Kubernetes@1 143 | displayName: 'kubectl apply' 144 | inputs: 145 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 146 | azureResourceGroup: '$(Azure.ResourceGroupName)' 147 | kubernetesCluster: '$(AKS.ClusterName)' 148 | arguments: '-f $(AKS.KubeDeploymentYaml)' 149 | command: 'apply' 150 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/filesNotCurrentlyWorking/xcode.yml: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # Build, test, and archive an Xcode workspace on macOS. 3 | # Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/xcode 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'macos-latest' 11 | 12 | steps: 13 | - task: Xcode@5 14 | inputs: 15 | actions: 'build' 16 | scheme: '' 17 | sdk: 'iphoneos' 18 | configuration: 'Release' 19 | xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' 20 | xcodeVersion: 'default' # Options: 8, 9, 10, default, specifyPath 21 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/.net-desktop.yml: -------------------------------------------------------------------------------- 1 | # .NET Desktop 2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'windows-latest' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'Any CPU' 15 | buildConfiguration: 'Release' 16 | 17 | steps: 18 | - task: NuGetToolInstaller@1 19 | 20 | - task: NuGetCommand@2 21 | inputs: 22 | restoreSolution: '$(solution)' 23 | 24 | - task: VSBuild@1 25 | inputs: 26 | solution: '$(solution)' 27 | platform: '$(buildPlatform)' 28 | configuration: '$(buildConfiguration)' 29 | 30 | - task: VSTest@2 31 | inputs: 32 | platform: '$(buildPlatform)' 33 | configuration: '$(buildConfiguration)' 34 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/android.yml: -------------------------------------------------------------------------------- 1 | # Android 2 | # Build your Android project with Gradle. 3 | # Add steps that test, sign, and distribute the APK, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/android 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'macos-latest' 11 | 12 | steps: 13 | - task: Gradle@2 14 | inputs: 15 | workingDirectory: '' 16 | gradleWrapperFile: 'gradlew' 17 | gradleOptions: '-Xmx3072m' 18 | publishJUnitResults: false 19 | testResultsFiles: '**/TEST-*.xml' 20 | tasks: 'assembleDebug' 21 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/ant.yml: -------------------------------------------------------------------------------- 1 | # Ant 2 | # Build your Java projects and run tests with Apache Ant. 3 | # Add steps that save build artifacts and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: Ant@1 14 | inputs: 15 | workingDirectory: '' 16 | buildFile: 'build.xml' 17 | javaHomeOption: 'JDKVersion' 18 | jdkVersionOption: '1.8' 19 | jdkArchitectureOption: 'x64' 20 | publishJUnitResults: true 21 | testResultsFiles: '**/TEST-*.xml' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/asp.net-core-.net-framework.yml: -------------------------------------------------------------------------------- 1 | # ASP.NET Core (.NET Framework) 2 | # Build and test ASP.NET Core projects targeting the full .NET Framework. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'windows-latest' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'Any CPU' 15 | buildConfiguration: 'Release' 16 | 17 | steps: 18 | - task: NuGetToolInstaller@1 19 | 20 | - task: NuGetCommand@2 21 | inputs: 22 | restoreSolution: '$(solution)' 23 | 24 | - task: VSBuild@1 25 | inputs: 26 | solution: '$(solution)' 27 | msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"' 28 | platform: '$(buildPlatform)' 29 | configuration: '$(buildConfiguration)' 30 | 31 | - task: VSTest@2 32 | inputs: 33 | platform: '$(buildPlatform)' 34 | configuration: '$(buildConfiguration)' 35 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/asp.net-core-functionapp-to-windows-on-azure.yml: -------------------------------------------------------------------------------- 1 | # .NET Core Function App to Windows on Azure 2 | # Build a .NET Core function app and deploy it to Azure as a Windows function App. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | # Azure Resource Manager connection created during pipeline creation 11 | azureSubscription: '{{ azureRmConnection.Id }}' 12 | 13 | # Function app name 14 | functionAppName: '{{ functionAppName }}' 15 | 16 | # Agent VM image name 17 | vmImageName: 'vs2017-win2016' 18 | 19 | # Working Directory 20 | workingDirectory: '{{ workingDirectory }}' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build stage 25 | 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - task: DotNetCoreCLI@2 34 | displayName: Build 35 | inputs: 36 | command: 'build' 37 | projects: | 38 | $(workingDirectory)/*.csproj 39 | arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release 40 | 41 | - task: ArchiveFiles@2 42 | displayName: 'Archive files' 43 | inputs: 44 | rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' 45 | includeRootFolder: false 46 | archiveType: zip 47 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 48 | replaceExistingArchive: true 49 | 50 | - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 51 | artifact: drop 52 | 53 | - stage: Deploy 54 | displayName: Deploy stage 55 | dependsOn: Build 56 | condition: succeeded() 57 | 58 | jobs: 59 | - deployment: Deploy 60 | displayName: Deploy 61 | environment: 'development' 62 | pool: 63 | vmImage: $(vmImageName) 64 | 65 | strategy: 66 | runOnce: 67 | deploy: 68 | 69 | steps: 70 | - task: AzureFunctionApp@1 71 | displayName: 'Azure functions app deploy' 72 | inputs: 73 | azureSubscription: '$(azureSubscription)' 74 | appType: functionApp 75 | appName: $(functionAppName) 76 | package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/asp.net-core.yml: -------------------------------------------------------------------------------- 1 | # ASP.NET Core 2 | # Build and test ASP.NET Core projects targeting .NET Core. 3 | # Add steps that run tests, create a NuGet package, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | variables: 13 | buildConfiguration: 'Release' 14 | 15 | steps: 16 | - script: dotnet build --configuration $(buildConfiguration) 17 | displayName: 'dotnet build $(buildConfiguration)' 18 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/asp.net.yml: -------------------------------------------------------------------------------- 1 | # ASP.NET 2 | # Build and test ASP.NET projects. 3 | # Add steps that publish symbols, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'windows-latest' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'Any CPU' 15 | buildConfiguration: 'Release' 16 | 17 | steps: 18 | - task: NuGetToolInstaller@1 19 | 20 | - task: NuGetCommand@2 21 | inputs: 22 | restoreSolution: '$(solution)' 23 | 24 | - task: VSBuild@1 25 | inputs: 26 | solution: '$(solution)' 27 | msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"' 28 | platform: '$(buildPlatform)' 29 | configuration: '$(buildConfiguration)' 30 | 31 | - task: VSTest@2 32 | inputs: 33 | platform: '$(buildPlatform)' 34 | configuration: '$(buildConfiguration)' 35 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/docker-build.yml: -------------------------------------------------------------------------------- 1 | # Docker 2 | # Build a Docker image 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | tag: '$(Build.BuildId)' 13 | 14 | stages: 15 | - stage: Build 16 | displayName: Build image 17 | jobs: 18 | - job: Build 19 | displayName: Build 20 | pool: 21 | vmImage: 'ubuntu-latest' 22 | steps: 23 | - task: Docker@2 24 | displayName: Build an image 25 | inputs: 26 | command: build 27 | dockerfile: '{{ dockerfilePath }}' 28 | tags: | 29 | $(tag) -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/docker-container-functionapp.yml: -------------------------------------------------------------------------------- 1 | # Docker image, Azure Container Registry, and Azure Functions app 2 | # Build a Docker image, push it to an Azure Container Registry, and deploy it to an Azure Functions app. 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # ======================================================================== 13 | # Mandatory variables 14 | # ======================================================================== 15 | 16 | # Update Azure.ResourceGroupName value with Azure resource group name. 17 | Azure.ResourceGroupName: '{{#toAlphaNumericString repositoryName 50}}{{/toAlphaNumericString}}' 18 | 19 | # Update Azure.ServiceConnectionId value with AzureRm service endpoint. 20 | Azure.ServiceConnectionId: '{{ azureServiceConnectionId }}' 21 | 22 | # Update Azure.Location value with Azure Location. 23 | Azure.Location: 'eastus' 24 | 25 | # Update ACR.Name value with ACR name. Please note ACR names should be all lower-case and alphanumeric only. 26 | ACR.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 27 | 28 | # Update FunctionApp.Name value with a name that identifies your new function app. Valid characters are a-z, 0-9, and -. 29 | FunctionApp.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 30 | 31 | # Update StorageAccount.Name value with Storage account name. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only. 32 | StorageAccount.Name: '{{#toAlphaNumericString repositoryName 20}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 33 | 34 | # Update ServicePlan.Name value with a name of the app service plan. 35 | ServicePlan.Name: '{{#toAlphaNumericString repositoryName 45}}{{/toAlphaNumericString}}-plan' 36 | 37 | # ======================================================================== 38 | # Optional variables 39 | # ======================================================================== 40 | 41 | ACR.ImageName: '$(ACR.Name):$(Build.BuildId)' 42 | ACR.FullName: '$(ACR.Name).azurecr.io' 43 | ACR.Sku: 'Standard' 44 | Azure.CreateResources: 'true' # Update Azure.CreateResources to false if you have already created resources like resource group and azure container registry. 45 | System.Debug: 'false' 46 | 47 | jobs: 48 | 49 | - job: CreateResources 50 | displayName: Create resources 51 | condition: and(succeeded(), eq(variables['Azure.CreateResources'], 'true')) 52 | 53 | pool: 54 | vmImage: 'ubuntu-latest' 55 | 56 | steps: 57 | - task: AzureResourceGroupDeployment@2 58 | displayName: 'Azure Deployment:Create Azure Container Registry, Azure WebApp Service' 59 | inputs: 60 | azureSubscription: '$(Azure.ServiceConnectionId)' 61 | resourceGroupName: '$(Azure.ResourceGroupName)' 62 | location: '$(Azure.Location)' 63 | templateLocation: 'URL of the file' 64 | csmFileLink: 'https://raw.githubusercontent.com/Microsoft/azure-pipelines-yaml/master/templates/resources/arm/functionapp.json' 65 | overrideParameters: '-registryName "$(ACR.Name)" -registryLocation "$(Azure.Location)" -functionAppName "$(FunctionApp.Name)" -hostingPlanName "$(ServicePlan.Name)" -storageAccountName "$(StorageAccount.Name)"' 66 | 67 | - job: BuildImage 68 | displayName: Build 69 | dependsOn: CreateResources 70 | condition: or(succeeded(), ne(variables['Azure.CreateResources'], 'true')) 71 | 72 | pool: 73 | vmImage: 'ubuntu-latest' 74 | 75 | steps: 76 | - task: Docker@1 77 | displayName: 'Build an image' 78 | inputs: 79 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 80 | azureContainerRegistry: '$(ACR.FullName)' 81 | imageName: '$(ACR.ImageName)' 82 | command: build 83 | dockerFile: '**/Dockerfile' 84 | 85 | - task: Docker@1 86 | displayName: 'Push an image' 87 | inputs: 88 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 89 | azureContainerRegistry: '$(ACR.FullName)' 90 | imageName: '$(ACR.ImageName)' 91 | command: push 92 | 93 | - job: DeployApp 94 | displayName: Deploy 95 | dependsOn: BuildImage 96 | condition: succeeded() 97 | 98 | pool: 99 | vmImage: 'ubuntu-latest' 100 | 101 | steps: 102 | - task: AzureFunctionAppContainer@1 103 | displayName: 'Azure Function App on Container Deploy: $(FunctionApp.Name)' 104 | inputs: 105 | azureSubscription: '$(Azure.ServiceConnectionId)' 106 | appName: $(FunctionApp.Name) 107 | imageName: '$(ACR.FullName)/$(ACR.ImageName)' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/docker-container-to-acr.yml: -------------------------------------------------------------------------------- 1 | # Docker image and Azure Container Registry 2 | # Build a Docker image and push it to an Azure Container Registry. 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # ======================================================================== 13 | # Mandatory variables 14 | # ======================================================================== 15 | 16 | # Update Azure.ResourceGroupName value with Azure resource group name. 17 | Azure.ResourceGroupName: '{{#toAlphaNumericString repositoryName 50}}{{/toAlphaNumericString}}' 18 | 19 | # Update Azure.ServiceConnectionId value with AzureRm service endpoint. 20 | Azure.ServiceConnectionId: '{{ azureServiceConnectionId }}' 21 | 22 | # Update Azure.Location value with Azure Location. 23 | Azure.Location: 'eastus' 24 | 25 | # Update ACR.Name value with ACR name. Please note ACR names should be all lower-case and alphanumeric only. 26 | ACR.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 27 | 28 | # ======================================================================== 29 | # Optional variables 30 | # ======================================================================== 31 | 32 | ACR.ImageName: '$(ACR.Name):$(Build.BuildId)' 33 | ACR.FullName: '$(ACR.Name).azurecr.io' 34 | Azure.CreateResources: 'true' # Update Azure.CreateResources to false if you have already created resources like resource group and azure container registry. 35 | System.Debug: 'false' 36 | 37 | jobs: 38 | 39 | - job: CreateResources 40 | displayName: Create required resources 41 | condition: and(succeeded(), eq(variables['Azure.CreateResources'], 'true')) 42 | 43 | pool: 44 | vmImage: 'ubuntu-latest' 45 | 46 | steps: 47 | - task: AzureResourceGroupDeployment@2 48 | displayName: 'Azure Deployment:Create Azure Container Registry' 49 | inputs: 50 | azureSubscription: '$(Azure.ServiceConnectionId)' 51 | resourceGroupName: '$(Azure.ResourceGroupName)' 52 | location: '$(Azure.Location)' 53 | templateLocation: 'URL of the file' 54 | csmFileLink: 'https://raw.githubusercontent.com/Microsoft/azure-pipelines-yaml/master/templates/resources/arm/acr.json' 55 | overrideParameters: '-registryName "$(ACR.Name)" -registryLocation "$(Azure.Location)"' 56 | 57 | - job: BuildImage 58 | displayName: Build 59 | dependsOn: CreateResources 60 | condition: or(succeeded(), ne(variables['Azure.CreateResources'], 'true')) 61 | 62 | pool: 63 | vmImage: 'ubuntu-latest' 64 | 65 | steps: 66 | - task: Docker@1 67 | displayName: 'Build an image' 68 | inputs: 69 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 70 | azureContainerRegistry: '$(ACR.FullName)' 71 | imageName: '$(ACR.ImageName)' 72 | command: build 73 | dockerFile: '**/Dockerfile' 74 | 75 | - task: Docker@1 76 | displayName: 'Push an image' 77 | inputs: 78 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 79 | azureContainerRegistry: '$(ACR.FullName)' 80 | imageName: '$(ACR.ImageName)' 81 | command: push 82 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/docker-container-webapp.yml: -------------------------------------------------------------------------------- 1 | # Docker image, Azure Container Registry, and Azure Web App 2 | # Build a Docker image, push it to an Azure Container Registry, and deploy it to an Azure Web App. 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # ======================================================================== 13 | # Mandatory variables 14 | # ======================================================================== 15 | 16 | # Update Azure.ResourceGroupName value with Azure resource group name. 17 | Azure.ResourceGroupName: '{{#toAlphaNumericString repositoryName 50}}{{/toAlphaNumericString}}' 18 | 19 | # Update Azure.ServiceConnectionId value with AzureRm service endpoint. 20 | Azure.ServiceConnectionId: '{{ azureServiceConnectionId }}' 21 | 22 | # Update Azure.Location value with Azure Location. 23 | Azure.Location: 'eastus' 24 | 25 | # Update ACR.Name value with ACR name. Please note ACR names should be all lower-case and alphanumeric only. 26 | ACR.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 27 | 28 | # Update Web.Name value with a name that identifies your new Web app. Valid characters are a-z, 0-9, and -. 29 | WebApp.Name: '{{#toAlphaNumericString repositoryName 46}}{{/toAlphaNumericString}}{{#shortGuid}}{{/shortGuid}}' 30 | 31 | # Update ServicePlan.Name value with a name of the app service plan. 32 | ServicePlan.Name: '{{#toAlphaNumericString repositoryName 45}}{{/toAlphaNumericString}}-plan' 33 | 34 | # ======================================================================== 35 | # Optional variables 36 | # ======================================================================== 37 | 38 | ACR.ImageName: '$(ACR.Name):$(Build.BuildId)' 39 | ACR.FullName: '$(ACR.Name).azurecr.io' 40 | Azure.CreateResources: 'true' # Update Azure.CreateResources to false if you have already created resources like resource group and azure container registry. 41 | System.Debug: 'false' 42 | 43 | jobs: 44 | 45 | - job: CreateResources 46 | displayName: Create resources 47 | condition: and(succeeded(), eq(variables['Azure.CreateResources'], 'true')) 48 | 49 | pool: 50 | vmImage: 'ubuntu-latest' 51 | 52 | steps: 53 | - task: AzureResourceGroupDeployment@2 54 | displayName: 'Azure Deployment:Create Azure Container Registry, Azure WebApp Service' 55 | inputs: 56 | azureSubscription: '$(Azure.ServiceConnectionId)' 57 | resourceGroupName: '$(Azure.ResourceGroupName)' 58 | location: '$(Azure.Location)' 59 | templateLocation: 'URL of the file' 60 | csmFileLink: 'https://raw.githubusercontent.com/Microsoft/azure-pipelines-yaml/master/templates/resources/arm/webapp-on-containers.json' 61 | overrideParameters: '-registryName "$(ACR.Name)" -registryLocation "$(Azure.Location)" -imageName "$(ACR.ImageName)" -webAppName "$(WebApp.Name)" -hostingPlanName "$(ServicePlan.Name)"' 62 | 63 | - job: BuildImage 64 | displayName: Build 65 | dependsOn: CreateResources 66 | condition: or(succeeded(), ne(variables['Azure.CreateResources'], 'true')) 67 | 68 | pool: 69 | vmImage: 'ubuntu-latest' 70 | 71 | steps: 72 | - task: Docker@1 73 | displayName: 'Build an image' 74 | inputs: 75 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 76 | azureContainerRegistry: '$(ACR.FullName)' 77 | imageName: '$(ACR.ImageName)' 78 | command: build 79 | dockerFile: '**/Dockerfile' 80 | 81 | - task: Docker@1 82 | displayName: 'Push an image' 83 | inputs: 84 | azureSubscriptionEndpoint: '$(Azure.ServiceConnectionId)' 85 | azureContainerRegistry: '$(ACR.FullName)' 86 | imageName: '$(ACR.ImageName)' 87 | command: push 88 | 89 | - job: DeployApp 90 | displayName: Deploy 91 | dependsOn: BuildImage 92 | condition: succeeded() 93 | 94 | pool: 95 | vmImage: 'ubuntu-latest' 96 | 97 | steps: 98 | - task: AzureWebAppContainer@1 99 | displayName: 'Azure Web App on Container Deploy: $(WebApp.Name)' 100 | inputs: 101 | azureSubscription: '$(Azure.ServiceConnectionId)' 102 | appName: $(WebApp.Name) 103 | imageName: '$(ACR.FullName)/$(ACR.ImageName)' 104 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/docker-container.yml: -------------------------------------------------------------------------------- 1 | # Docker 2 | # Build and push an image to Azure Container Registry 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - main 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # Container registry service connection established during pipeline creation 13 | dockerRegistryServiceConnection: '{{ containerRegistryConnection.Id }}' 14 | imageRepository: '{{#toAlphaNumericString imageRepository 50}}{{/toAlphaNumericString}}' 15 | containerRegistry: '{{ containerRegistryConnection.Authorization.Parameters.loginServer }}' 16 | dockerfilePath: '{{ dockerfilePath }}' 17 | tag: '$(Build.BuildId)' 18 | 19 | # Agent VM image name 20 | vmImageName: 'ubuntu-latest' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build and push stage 25 | jobs: 26 | - job: Build 27 | displayName: Build 28 | pool: 29 | vmImage: $(vmImageName) 30 | steps: 31 | - task: Docker@2 32 | displayName: Build and push an image to container registry 33 | inputs: 34 | command: buildAndPush 35 | repository: $(imageRepository) 36 | dockerfile: $(dockerfilePath) 37 | containerRegistry: $(dockerRegistryServiceConnection) 38 | tags: | 39 | $(tag) 40 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/empty.yml: -------------------------------------------------------------------------------- 1 | # Starter pipeline 2 | # Start with a minimal pipeline that you can customize to build and deploy your code. 3 | # Add steps that build, run tests, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - script: echo Hello, world! 14 | displayName: 'Run a one-line script' 15 | 16 | - script: | 17 | echo Add other tasks to build, test, and deploy your project. 18 | echo See https://aka.ms/yaml 19 | displayName: 'Run a multi-line script' 20 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/gcc.yml: -------------------------------------------------------------------------------- 1 | # C/C++ with GCC 2 | # Build your C/C++ project with GCC using make. 3 | # Add steps that publish test results, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - script: | 14 | make 15 | displayName: 'make' 16 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/go.yml: -------------------------------------------------------------------------------- 1 | # Go 2 | # Build your Go project. 3 | # Add steps that test, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/go 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | variables: 13 | GOBIN: '$(GOPATH)/bin' # Go binaries path 14 | GOROOT: '/usr/local/go1.11' # Go installation path 15 | GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path 16 | modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code 17 | 18 | steps: 19 | - script: | 20 | mkdir -p '$(GOBIN)' 21 | mkdir -p '$(GOPATH)/pkg' 22 | mkdir -p '$(modulePath)' 23 | shopt -s extglob 24 | shopt -s dotglob 25 | mv !(gopath) '$(modulePath)' 26 | echo '##vso[task.prependpath]$(GOBIN)' 27 | echo '##vso[task.prependpath]$(GOROOT)/bin' 28 | displayName: 'Set up the Go workspace' 29 | 30 | - script: | 31 | go version 32 | go get -v -t -d ./... 33 | if [ -f Gopkg.toml ]; then 34 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 35 | dep ensure 36 | fi 37 | go build -v . 38 | workingDirectory: '$(modulePath)' 39 | displayName: 'Get dependencies, then build' 40 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/gradle.yml: -------------------------------------------------------------------------------- 1 | # Gradle 2 | # Build your Java project and run tests with Gradle using a Gradle wrapper script. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: Gradle@2 14 | inputs: 15 | workingDirectory: '' 16 | gradleWrapperFile: 'gradlew' 17 | gradleOptions: '-Xmx3072m' 18 | javaHomeOption: 'JDKVersion' 19 | jdkVersionOption: '1.8' 20 | jdkArchitectureOption: 'x64' 21 | publishJUnitResults: true 22 | testResultsFiles: '**/TEST-*.xml' 23 | tasks: 'build' 24 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/html.yml: -------------------------------------------------------------------------------- 1 | # HTML 2 | # Archive your static HTML project and save it with the build record. 3 | # Add steps that build, run tests, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: ArchiveFiles@2 14 | inputs: 15 | rootFolderOrFile: '$(build.sourcesDirectory)' 16 | includeRootFolder: false 17 | - task: PublishBuildArtifacts@1 18 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/jekyll-container.yml: -------------------------------------------------------------------------------- 1 | # Jekyll site 2 | # Package your Jekyll site using the jekyll/builder Docker container image. 3 | # Add steps that build, test, save build artifacts, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: Docker@0 14 | displayName: 'Run Jekyll' 15 | inputs: 16 | containerRegistryType: 'Container Registry' 17 | action: 'Run an image' 18 | imageName: 'jekyll/builder:latest' 19 | volumes: | 20 | $(build.sourcesDirectory):/srv/jekyll 21 | $(build.binariesDirectory):/srv/jekyll/_site 22 | containerCommand: 'jekyll build --future' 23 | detached: false 24 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/maven-webapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Maven package Java project Web App to Linux on Azure 2 | # Build your Java project and deploy it to Azure as a Linux web app 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | 11 | # Azure Resource Manager connection created during pipeline creation 12 | azureSubscription: '{{ azureRmConnection.Id }}' 13 | 14 | # Web app name 15 | webAppName: '{{ webAppName }}' 16 | 17 | # Environment name 18 | environmentName: '{{ webAppName }}' 19 | 20 | # Agent VM image name 21 | vmImageName: 'ubuntu-latest' 22 | 23 | stages: 24 | - stage: Build 25 | displayName: Build stage 26 | jobs: 27 | - job: MavenPackageAndPublishArtifacts 28 | displayName: Maven Package and Publish Artifacts 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - task: Maven@3 34 | displayName: 'Maven Package' 35 | inputs: 36 | mavenPomFile: 'pom.xml' 37 | 38 | - task: CopyFiles@2 39 | displayName: 'Copy Files to artifact staging directory' 40 | inputs: 41 | SourceFolder: '$(System.DefaultWorkingDirectory)' 42 | Contents: '**/target/*.?(war|jar)' 43 | TargetFolder: $(Build.ArtifactStagingDirectory) 44 | 45 | - upload: $(Build.ArtifactStagingDirectory) 46 | artifact: drop 47 | 48 | - stage: Deploy 49 | displayName: Deploy stage 50 | dependsOn: Build 51 | condition: succeeded() 52 | jobs: 53 | - deployment: DeployLinuxWebApp 54 | displayName: Deploy Linux Web App 55 | environment: $(environmentName) 56 | pool: 57 | vmImage: $(vmImageName) 58 | strategy: 59 | runOnce: 60 | deploy: 61 | steps: 62 | - task: AzureWebApp@1 63 | displayName: 'Azure Web App Deploy: {{ webAppName }}' 64 | inputs: 65 | azureSubscription: $(azureSubscription) 66 | appType: webAppLinux 67 | appName: $(webAppName) 68 | package: '$(Pipeline.Workspace)/drop/**/target/*.?(war|jar)' 69 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/maven.yml: -------------------------------------------------------------------------------- 1 | # Maven 2 | # Build your Java project and run tests with Apache Maven. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/java 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: Maven@3 14 | inputs: 15 | mavenPomFile: 'pom.xml' 16 | mavenOptions: '-Xmx3072m' 17 | javaHomeOption: 'JDKVersion' 18 | jdkVersionOption: '1.8' 19 | jdkArchitectureOption: 'x64' 20 | publishJUnitResults: true 21 | testResultsFiles: '**/surefire-reports/TEST-*.xml' 22 | goals: 'package' 23 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-express-webapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Node.js Express Web App to Linux on Azure 2 | # Build a Node.js Express app and deploy it to Azure as a Linux web app. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | 11 | # Azure Resource Manager connection created during pipeline creation 12 | azureSubscription: '{{ azureRmConnection.Id }}' 13 | 14 | # Web app name 15 | webAppName: '{{ webAppName }}' 16 | 17 | # Environment name 18 | environmentName: '{{ webAppName }}' 19 | 20 | # Agent VM image name 21 | vmImageName: 'ubuntu-latest' 22 | 23 | stages: 24 | - stage: Build 25 | displayName: Build stage 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - task: NodeTool@0 34 | inputs: 35 | versionSpec: '10.x' 36 | displayName: 'Install Node.js' 37 | 38 | - script: | 39 | npm install 40 | npm run build --if-present 41 | npm run test --if-present 42 | displayName: 'npm install, build and test' 43 | 44 | - task: ArchiveFiles@2 45 | displayName: 'Archive files' 46 | inputs: 47 | rootFolderOrFile: '$(System.DefaultWorkingDirectory)' 48 | includeRootFolder: false 49 | archiveType: zip 50 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 51 | replaceExistingArchive: true 52 | 53 | - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 54 | artifact: drop 55 | 56 | - stage: Deploy 57 | displayName: Deploy stage 58 | dependsOn: Build 59 | condition: succeeded() 60 | jobs: 61 | - deployment: Deploy 62 | displayName: Deploy 63 | environment: $(environmentName) 64 | pool: 65 | vmImage: $(vmImageName) 66 | strategy: 67 | runOnce: 68 | deploy: 69 | steps: 70 | - task: AzureWebApp@1 71 | displayName: 'Azure Web App Deploy: {{ webAppName }}' 72 | inputs: 73 | azureSubscription: $(azureSubscription) 74 | appType: webAppLinux 75 | appName: $(webAppName) 76 | runtimeStack: 'NODE|10.10' 77 | package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip 78 | startUpCommand: 'npm run start' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-functionapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Node.js Function App to Linux on Azure 2 | # Build a Node.js function app and deploy it to Azure as a Linux function app. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | 11 | # Azure Resource Manager connection created during pipeline creation 12 | azureSubscription: '{{ azureRmConnection.Id }}' 13 | 14 | # Function app name 15 | functionAppName: '{{ functionAppName }}' 16 | 17 | # Environment name 18 | environmentName: '{{ functionAppName }}' 19 | 20 | # Agent VM image name 21 | vmImageName: 'ubuntu-latest' 22 | 23 | stages: 24 | - stage: Build 25 | displayName: Build stage 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - task: NodeTool@0 34 | inputs: 35 | versionSpec: '10.x' 36 | displayName: 'Install Node.js' 37 | 38 | - script: | 39 | if [ -f extensions.csproj ] 40 | then 41 | dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin 42 | fi 43 | displayName: 'Build extensions' 44 | 45 | - script: | 46 | npm install 47 | npm run build --if-present 48 | npm run test --if-present 49 | displayName: 'Prepare binaries' 50 | 51 | - task: ArchiveFiles@2 52 | displayName: 'Archive files' 53 | inputs: 54 | rootFolderOrFile: '$(System.DefaultWorkingDirectory)' 55 | includeRootFolder: false 56 | archiveType: zip 57 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 58 | replaceExistingArchive: true 59 | 60 | - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 61 | artifact: drop 62 | 63 | - stage: Deploy 64 | displayName: Deploy stage 65 | dependsOn: Build 66 | condition: succeeded() 67 | jobs: 68 | - deployment: Deploy 69 | displayName: Deploy 70 | environment: $(environmentName) 71 | pool: 72 | vmImage: $(vmImageName) 73 | strategy: 74 | runOnce: 75 | deploy: 76 | steps: 77 | - task: AzureFunctionApp@1 78 | displayName: 'Azure Functions App Deploy: {{ functionAppName }}' 79 | inputs: 80 | azureSubscription: '$(azureSubscription)' 81 | appType: functionAppLinux 82 | appName: $(functionAppName) 83 | package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-react-webapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Node.js React Web App to Linux on Azure 2 | # Build a Node.js React app and deploy it to Azure as a Linux web app. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | 11 | # Azure Resource Manager connection created during pipeline creation 12 | azureSubscription: '{{ azureRmConnection.Id }}' 13 | 14 | # Web app name 15 | webAppName: '{{ webAppName }}' 16 | 17 | # Environment name 18 | environmentName: '{{ webAppName }}' 19 | 20 | # Agent VM image name 21 | vmImageName: 'ubuntu-latest' 22 | 23 | stages: 24 | - stage: Build 25 | displayName: Build stage 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - task: ArchiveFiles@2 34 | displayName: 'Archive files' 35 | inputs: 36 | rootFolderOrFile: '$(System.DefaultWorkingDirectory)' 37 | includeRootFolder: false 38 | archiveType: zip 39 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 40 | replaceExistingArchive: true 41 | 42 | - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 43 | artifact: drop 44 | 45 | - stage: Deploy 46 | displayName: Deploy stage 47 | dependsOn: Build 48 | condition: succeeded() 49 | jobs: 50 | - deployment: Deploy 51 | displayName: Deploy 52 | environment: $(environmentName) 53 | pool: 54 | vmImage: $(vmImageName) 55 | strategy: 56 | runOnce: 57 | deploy: 58 | steps: 59 | - task: AzureRmWebAppDeployment@4 60 | displayName: 'Azure App Service Deploy: {{ webAppName }}' 61 | inputs: 62 | azureSubscription: $(azureSubscription) 63 | appType: webAppLinux 64 | WebAppName: $(webAppName) 65 | packageForLinux: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' 66 | RuntimeStack: 'NODE|10.10' 67 | StartupCommand: 'npm run start' 68 | ScriptType: 'Inline Script' 69 | InlineScript: | 70 | npm install 71 | npm run build --if-present -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-angular.yml: -------------------------------------------------------------------------------- 1 | # Node.js with Angular 2 | # Build a Node.js project that uses Angular. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install -g @angular/cli 20 | npm install 21 | ng build --prod 22 | displayName: 'npm install and build' 23 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-grunt.yml: -------------------------------------------------------------------------------- 1 | # Node.js with Grunt 2 | # Build a Node.js project using the Grunt task runner. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install 20 | grunt --gruntfile Gruntfile.js 21 | displayName: 'npm install and run grunt' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-gulp.yml: -------------------------------------------------------------------------------- 1 | # Node.js with gulp 2 | # Build a Node.js project using the gulp task runner. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install 20 | gulp default --gulpfile gulpfile.js 21 | displayName: 'npm install and run gulp' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-react.yml: -------------------------------------------------------------------------------- 1 | # Node.js with React 2 | # Build a Node.js project that uses React. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install 20 | npm run build 21 | displayName: 'npm install and build' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-vue.yml: -------------------------------------------------------------------------------- 1 | # Node.js with Vue 2 | # Build a Node.js project that uses Vue. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install 20 | npm run build 21 | displayName: 'npm install and build' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js-with-webpack.yml: -------------------------------------------------------------------------------- 1 | # Node.js with webpack 2 | # Build a Node.js project using the webpack CLI. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install -g webpack webpack-cli --save-dev 20 | npm install 21 | npx webpack --config webpack.config.js 22 | displayName: 'npm install, run webpack' 23 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/node.js.yml: -------------------------------------------------------------------------------- 1 | # Node.js 2 | # Build a general Node.js project with npm. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: NodeTool@0 14 | inputs: 15 | versionSpec: '10.x' 16 | displayName: 'Install Node.js' 17 | 18 | - script: | 19 | npm install 20 | npm run build 21 | displayName: 'npm install and build' 22 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/php-webapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # PHP as Linux Web App on Azure 2 | # Build, package and deploy your PHP project to Azure Linux Web App. 3 | # Add steps that run tests and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/php 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | # Azure Resource Manager connection created during pipeline creation 11 | azureSubscription: '{{ azureRmServiceConnection.Id }}' 12 | 13 | # Web app name 14 | webAppName: '{{ webAppName }}' 15 | 16 | # Agent VM image name 17 | vmImageName: 'ubuntu-latest' 18 | 19 | # Environment name 20 | environmentName: '{{ webAppName }}' 21 | 22 | # Root folder under which your composer.json file is available. 23 | rootFolder: $(System.DefaultWorkingDirectory) 24 | 25 | stages: 26 | - stage: Build 27 | displayName: Build stage 28 | variables: 29 | phpVersion: '7.3' 30 | jobs: 31 | - job: BuildJob 32 | pool: 33 | vmImage: $(vmImageName) 34 | steps: 35 | - script: | 36 | sudo update-alternatives --set php /usr/bin/php$(phpVersion) 37 | sudo update-alternatives --set phar /usr/bin/phar$(phpVersion) 38 | sudo update-alternatives --set phpdbg /usr/bin/phpdbg$(phpVersion) 39 | sudo update-alternatives --set php-cgi /usr/bin/php-cgi$(phpVersion) 40 | sudo update-alternatives --set phar.phar /usr/bin/phar.phar$(phpVersion) 41 | php -version 42 | workingDirectory: $(rootFolder) 43 | displayName: 'Use PHP version $(phpVersion)' 44 | 45 | - script: composer install --no-interaction --prefer-dist 46 | workingDirectory: $(rootFolder) 47 | displayName: 'Composer install' 48 | 49 | - task: ArchiveFiles@2 50 | displayName: 'Archive files' 51 | inputs: 52 | rootFolderOrFile: '$(rootFolder)' 53 | includeRootFolder: false 54 | archiveType: zip 55 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 56 | replaceExistingArchive: true 57 | 58 | - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 59 | displayName: 'Upload package' 60 | artifact: drop 61 | 62 | - stage: Deploy 63 | displayName: 'Deploy Web App' 64 | dependsOn: Build 65 | condition: succeeded() 66 | jobs: 67 | - deployment: DeploymentJob 68 | pool: 69 | vmImage: $(vmImageName) 70 | environment: $(environmentName) 71 | strategy: 72 | runOnce: 73 | deploy: 74 | steps: 75 | - task: AzureWebApp@1 76 | displayName: 'Deploy Azure Web App : {{ webAppName }}' 77 | inputs: 78 | azureSubscription: $(azureSubscription) 79 | appName: $(webAppName) 80 | package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/php.yml: -------------------------------------------------------------------------------- 1 | # PHP 2 | # Test and package your PHP project. 3 | # Add steps that run tests, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/php 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | variables: 13 | phpVersion: 7.2 14 | 15 | steps: 16 | - script: | 17 | sudo update-alternatives --set php /usr/bin/php$(phpVersion) 18 | sudo update-alternatives --set phar /usr/bin/phar$(phpVersion) 19 | sudo update-alternatives --set phpdbg /usr/bin/phpdbg$(phpVersion) 20 | sudo update-alternatives --set php-cgi /usr/bin/php-cgi$(phpVersion) 21 | sudo update-alternatives --set phar.phar /usr/bin/phar.phar$(phpVersion) 22 | php -version 23 | displayName: 'Use PHP version $(phpVersion)' 24 | 25 | - script: composer install --no-interaction --prefer-dist 26 | displayName: 'composer install' 27 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/powershell-functionapp-to-windows-on-azure.yml: -------------------------------------------------------------------------------- 1 | # PowerShell Function App to Windows on Azure 2 | # Build a PowerShell Function App and deploy it to Azure as a Windows function app. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | # Azure Resource Manager connection created during pipeline creation 11 | azureSubscription: '{{ azureRmConnection.Id }}' 12 | 13 | # Function app name 14 | functionAppName: '{{ functionAppName }}' 15 | 16 | # Agent VM image name 17 | vmImageName: 'windows-latest' 18 | 19 | # Working Directory 20 | workingDirectory: '{{ workingDirectory }}' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build stage 25 | 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - powershell: | 34 | if (Test-Path "extensions.csproj") { 35 | dotnet build extensions.csproj --output ./$(workingDirectory)/bin 36 | } 37 | displayName: 'Build extensions' 38 | 39 | - task: ArchiveFiles@2 40 | displayName: 'Archive files' 41 | inputs: 42 | rootFolderOrFile: $(workingDirectory) 43 | includeRootFolder: false 44 | archiveType: zip 45 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 46 | replaceExistingArchive: true 47 | 48 | - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 49 | artifact: drop 50 | 51 | - stage: Deploy 52 | displayName: Deploy stage 53 | dependsOn: Build 54 | condition: succeeded() 55 | 56 | jobs: 57 | - deployment: Deploy 58 | displayName: Deploy 59 | environment: $(functionAppName) 60 | pool: 61 | vmImage: $(vmImageName) 62 | 63 | strategy: 64 | runOnce: 65 | deploy: 66 | 67 | steps: 68 | - task: AzureFunctionApp@1 69 | displayName: 'Azure functions app deploy' 70 | inputs: 71 | azureSubscription: '$(azureSubscription)' 72 | appType: functionApp 73 | appName: $(functionAppName) 74 | package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/python-django.yml: -------------------------------------------------------------------------------- 1 | # Python Django 2 | # Test a Django project on multiple versions of Python. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | strategy: 12 | matrix: 13 | Python35: 14 | PYTHON_VERSION: '3.5' 15 | Python36: 16 | PYTHON_VERSION: '3.6' 17 | Python37: 18 | PYTHON_VERSION: '3.7' 19 | maxParallel: 3 20 | 21 | steps: 22 | - task: UsePythonVersion@0 23 | inputs: 24 | versionSpec: '$(PYTHON_VERSION)' 25 | architecture: 'x64' 26 | 27 | - task: PythonScript@0 28 | displayName: 'Export project path' 29 | inputs: 30 | scriptSource: 'inline' 31 | script: | 32 | """Search all subdirectories for `manage.py`.""" 33 | from glob import iglob 34 | from os import path 35 | # Python >= 3.5 36 | manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) 37 | if not manage_py: 38 | raise SystemExit('Could not find a Django project') 39 | project_location = path.dirname(path.abspath(manage_py)) 40 | print('Found Django project in', project_location) 41 | print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) 42 | 43 | - script: | 44 | python -m pip install --upgrade pip setuptools wheel 45 | pip install -r requirements.txt 46 | pip install unittest-xml-reporting 47 | displayName: 'Install prerequisites' 48 | 49 | - script: | 50 | pushd '$(projectRoot)' 51 | python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input 52 | displayName: 'Run tests' 53 | 54 | #- task: PublishTestResults@2 55 | # inputs: 56 | # testResultsFiles: "**/TEST-*.xml" 57 | # testRunTitle: 'Python $(PYTHON_VERSION)' 58 | # condition: succeededOrFailed() 59 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/python-functionapp-to-linux-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Python Function App to Linux on Azure 2 | # Build a Python function app and deploy it to Azure as a Linux function app. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | # Azure Resource Manager connection created during pipeline creation 11 | azureSubscription: '{{ azureRmConnection.Id }}' 12 | 13 | # Function app name 14 | functionAppName: '{{ functionAppName }}' 15 | 16 | # Agent VM image name 17 | vmImageName: 'ubuntu-latest' 18 | 19 | # Working Directory 20 | workingDirectory: '{{ workingDirectory }}' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build stage 25 | 26 | jobs: 27 | - job: Build 28 | displayName: Build 29 | pool: 30 | vmImage: $(vmImageName) 31 | 32 | steps: 33 | - bash: | 34 | if [ -f extensions.csproj ] 35 | then 36 | dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin 37 | fi 38 | workingDirectory: $(workingDirectory) 39 | displayName: 'Build extensions' 40 | 41 | - task: UsePythonVersion@0 42 | displayName: 'Use Python 3.6' 43 | inputs: 44 | versionSpec: 3.6 # Functions V2 supports Python 3.6 as of today 45 | 46 | - bash: | 47 | python -m venv worker_venv 48 | source worker_venv/bin/activate 49 | pip install -r requirements.txt 50 | workingDirectory: $(workingDirectory) 51 | displayName: 'Install application dependencies' 52 | 53 | - task: ArchiveFiles@2 54 | displayName: 'Archive files' 55 | inputs: 56 | rootFolderOrFile: '$(workingDirectory)' 57 | includeRootFolder: false 58 | archiveType: zip 59 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 60 | replaceExistingArchive: true 61 | 62 | - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 63 | artifact: drop 64 | 65 | - stage: Deploy 66 | displayName: Deploy stage 67 | dependsOn: Build 68 | condition: succeeded() 69 | 70 | jobs: 71 | - deployment: Deploy 72 | displayName: Deploy 73 | environment: 'development' 74 | pool: 75 | vmImage: $(vmImageName) 76 | 77 | strategy: 78 | runOnce: 79 | deploy: 80 | 81 | steps: 82 | - task: AzureFunctionApp@1 83 | displayName: 'Azure functions app deploy' 84 | inputs: 85 | azureSubscription: '$(azureSubscription)' 86 | appType: functionAppLinux 87 | appName: $(functionAppName) 88 | package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/python-package.yml: -------------------------------------------------------------------------------- 1 | # Python package 2 | # Create and test a Python package on multiple Python versions. 3 | # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | strategy: 12 | matrix: 13 | Python27: 14 | python.version: '2.7' 15 | Python35: 16 | python.version: '3.5' 17 | Python36: 18 | python.version: '3.6' 19 | Python37: 20 | python.version: '3.7' 21 | 22 | steps: 23 | - task: UsePythonVersion@0 24 | inputs: 25 | versionSpec: '$(python.version)' 26 | displayName: 'Use Python $(python.version)' 27 | 28 | - script: | 29 | python -m pip install --upgrade pip 30 | pip install -r requirements.txt 31 | displayName: 'Install dependencies' 32 | 33 | - script: | 34 | pip install pytest pytest-azurepipelines 35 | pytest 36 | displayName: 'pytest' 37 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/python-to-linux-webapp-on-azure.yml: -------------------------------------------------------------------------------- 1 | # Python to Linux Web App on Azure 2 | # Build your Python project and deploy it to Azure as a Linux Web App. 3 | # Change python version to one thats appropriate for your application. 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | trigger: 7 | - main 8 | 9 | variables: 10 | # Azure Resource Manager connection created during pipeline creation 11 | azureServiceConnectionId: '{{ azureServiceConnection.Id }}' 12 | 13 | # Web app name 14 | webAppName: '{{ webAppName }}' 15 | 16 | # Agent VM image name 17 | vmImageName: 'ubuntu-latest' 18 | 19 | # Environment name 20 | environmentName: '{{ webAppName }}' 21 | 22 | # Project root folder. Point to the folder containing manage.py file. 23 | projectRoot: $(System.DefaultWorkingDirectory) 24 | 25 | # Python version: 3.7 26 | pythonVersion: '3.7' 27 | 28 | stages: 29 | - stage: Build 30 | displayName: Build stage 31 | jobs: 32 | - job: BuildJob 33 | pool: 34 | vmImage: $(vmImageName) 35 | steps: 36 | - task: UsePythonVersion@0 37 | inputs: 38 | versionSpec: '$(pythonVersion)' 39 | displayName: 'Use Python $(pythonVersion)' 40 | 41 | - script: | 42 | python -m venv antenv 43 | source antenv/bin/activate 44 | python -m pip install --upgrade pip 45 | pip install setup 46 | pip install -r requirements.txt 47 | workingDirectory: $(projectRoot) 48 | displayName: "Install requirements" 49 | 50 | - task: ArchiveFiles@2 51 | displayName: 'Archive files' 52 | inputs: 53 | rootFolderOrFile: '$(projectRoot)' 54 | includeRootFolder: false 55 | archiveType: zip 56 | archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 57 | replaceExistingArchive: true 58 | 59 | - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip 60 | displayName: 'Upload package' 61 | artifact: drop 62 | 63 | - stage: Deploy 64 | displayName: 'Deploy Web App' 65 | dependsOn: Build 66 | condition: succeeded() 67 | jobs: 68 | - deployment: DeploymentJob 69 | pool: 70 | vmImage: $(vmImageName) 71 | environment: $(environmentName) 72 | strategy: 73 | runOnce: 74 | deploy: 75 | steps: 76 | 77 | - task: UsePythonVersion@0 78 | inputs: 79 | versionSpec: '$(pythonVersion)' 80 | displayName: 'Use Python version' 81 | 82 | - task: AzureWebApp@1 83 | displayName: 'Deploy Azure Web App : {{ webAppName }}' 84 | inputs: 85 | azureSubscription: $(azureServiceConnectionId) 86 | appName: $(webAppName) 87 | package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/ruby.yml: -------------------------------------------------------------------------------- 1 | # Ruby 2 | # Package your Ruby project. 3 | # Add steps that install rails, analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/ruby 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'ubuntu-latest' 11 | 12 | steps: 13 | - task: UseRubyVersion@0 14 | inputs: 15 | versionSpec: '>= 2.5' 16 | 17 | - script: | 18 | gem install bundler 19 | bundle install --retry=3 --jobs=4 20 | displayName: 'bundle install' 21 | 22 | - script: bundle exec rake 23 | displayName: 'bundle exec rake' 24 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/universal-windows-platform.yml: -------------------------------------------------------------------------------- 1 | # Universal Windows Platform 2 | # Build a Universal Windows Platform project using Visual Studio. 3 | # Add steps that test and distribute an app, save build artifacts, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'windows-latest' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'x86|x64|ARM' 15 | buildConfiguration: 'Release' 16 | appxPackageDir: '$(build.artifactStagingDirectory)\AppxPackages\\' 17 | 18 | steps: 19 | - task: NuGetToolInstaller@1 20 | 21 | - task: NuGetCommand@2 22 | inputs: 23 | restoreSolution: '$(solution)' 24 | 25 | - task: VSBuild@1 26 | inputs: 27 | platform: 'x86' 28 | solution: '$(solution)' 29 | configuration: '$(buildConfiguration)' 30 | msbuildArgs: '/p:AppxBundlePlatforms="$(buildPlatform)" /p:AppxPackageDir="$(appxPackageDir)" /p:AppxBundle=Always /p:UapAppxPackageBuildMode=StoreUpload' 31 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/xamarin.android.yml: -------------------------------------------------------------------------------- 1 | # Xamarin.Android 2 | # Build a Xamarin.Android project. 3 | # Add steps that test, sign, and distribute an app, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/xamarin 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'macos-latest' 11 | 12 | variables: 13 | buildConfiguration: 'Release' 14 | outputDirectory: '$(build.binariesDirectory)/$(buildConfiguration)' 15 | 16 | steps: 17 | - task: NuGetToolInstaller@1 18 | 19 | - task: NuGetCommand@2 20 | inputs: 21 | restoreSolution: '**/*.sln' 22 | 23 | - task: XamarinAndroid@1 24 | inputs: 25 | projectFile: '**/*droid*.csproj' 26 | outputDirectory: '$(outputDirectory)' 27 | configuration: '$(buildConfiguration)' 28 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.Tests/yamlFiles/xamarin.ios.yml: -------------------------------------------------------------------------------- 1 | # Xamarin.iOS 2 | # Build a Xamarin.iOS project. 3 | # Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/xamarin 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: 'macos-latest' 11 | 12 | steps: 13 | # To manually select a Xamarin SDK version on the Microsoft-hosted macOS agent, 14 | # configure this task with the *Mono* version that is associated with the 15 | # Xamarin SDK version that you need, and set the "enabled" property to true. 16 | # See https://go.microsoft.com/fwlink/?linkid=871629 17 | - script: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_12_0 18 | displayName: 'Select the Xamarin SDK version' 19 | enabled: false 20 | 21 | - task: NuGetToolInstaller@1 22 | 23 | - task: NuGetCommand@2 24 | inputs: 25 | restoreSolution: '**/*.sln' 26 | 27 | - task: XamariniOS@2 28 | inputs: 29 | solutionFile: '**/*.sln' 30 | configuration: 'Release' 31 | buildForSimulator: true 32 | packageApp: false 33 | -------------------------------------------------------------------------------- /src/AzurePipelinesToGitHubActionsConverter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29326.143 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzurePipelinesToGitHubActionsConverter.Core", "AzurePipelinesToGitHubActionsConverter.Core\AzurePipelinesToGitHubActionsConverter.Core.csproj", "{9243A833-7114-446F-8E2E-38C78965CDA8}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzurePipelinesToGitHubActionsConverter.Tests", "AzurePipelinesToGitHubActionsConverter.Tests\AzurePipelinesToGitHubActionsConverter.Tests.csproj", "{102D54AE-A0FB-4CE8-972E-5B0A4CF61F7A}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{90C45174-BE52-4642-BBB4-609E29A8CE48}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | ..\.github\workflows\CI.yml = ..\.github\workflows\CI.yml 14 | ..\.github\workflows\codeql-analysis.yml = ..\.github\workflows\codeql-analysis.yml 15 | ..\.github\dependabot.yml = ..\.github\dependabot.yml 16 | ..\GitVersion.yml = ..\GitVersion.yml 17 | ..\README.md = ..\README.md 18 | EndProjectSection 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {9243A833-7114-446F-8E2E-38C78965CDA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {9243A833-7114-446F-8E2E-38C78965CDA8}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {9243A833-7114-446F-8E2E-38C78965CDA8}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {9243A833-7114-446F-8E2E-38C78965CDA8}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {102D54AE-A0FB-4CE8-972E-5B0A4CF61F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {102D54AE-A0FB-4CE8-972E-5B0A4CF61F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {102D54AE-A0FB-4CE8-972E-5B0A4CF61F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {102D54AE-A0FB-4CE8-972E-5B0A4CF61F7A}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {4D8E37AA-02EB-4C52-8143-11B8ED7BECAC} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /src/BuildVersion.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [string] $ProjectFile 4 | ) 5 | 6 | Write-Host "Generating Build Number" 7 | 8 | #Get the version from the csproj file 9 | $xml = [Xml] (Get-Content $ProjectFile) 10 | $initialVersion = [Version] $xml.Project.PropertyGroup.Version 11 | Write-Host "Initial version read from project file: $initialVersion" 12 | $splitVersion = $initialVersion -Split "\." 13 | 14 | #Get the build number (number of days since January 1, 2000) 15 | $baseDate = [datetime]"01/01/2000" 16 | $currentDate = $(Get-Date) 17 | $interval = (NEW-TIMESPAN -Start $baseDate -End $currentDate) 18 | $buildNumber = $interval.Days 19 | #Write-Host $buildNumber 20 | 21 | #Get the revision number (number seconds (divided by two) into the day on which the compilation was performed) 22 | $StartDate=[datetime]::Today 23 | $EndDate=(GET-DATE) 24 | $revisionNumber = [math]::Round((New-TimeSpan -Start $StartDate -End $EndDate).TotalSeconds / 2,0) 25 | #Write-Host $revisionNumber 26 | 27 | #Final version number, using the Major, Minor and Patch versions, and then appends build and revision number together 28 | $finalBuildVersion = "$($splitVersion[0]).$($splitVersion[1]).$($splitVersion[2]).$($buildNumber)$($revisionNumber.ToString("00000"))" 29 | #Write-Host "Major.Minor,patch,Build+Revision" 30 | Write-Host "Final build number: $finalBuildVersion" 31 | #Writing final version number back to Github variable 32 | #Write-Host "Writing final version $finalBuildVersion back to Github variable" 33 | echo "::set-env name=buildVersion::$finalBuildVersion" 34 | #echo "buildVersion=$finalBuildVersion" >> $GITHUB_ENV 35 | 36 | --------------------------------------------------------------------------------