├── .gitignore ├── images ├── image1.png ├── image10.png ├── image100.png ├── image101.png ├── image102.png ├── image103.png ├── image104.png ├── image105.png ├── image106.png ├── image11.png ├── image12.png ├── image13.png ├── image14.png ├── image15.png ├── image16.png ├── image17.png ├── image18.png ├── image19.png ├── image2.png ├── image20.png ├── image21.png ├── image22.png ├── image23.png ├── image24.png ├── image25.png ├── image26.png ├── image27.png ├── image28.png ├── image29.png ├── image3.png ├── image30.png ├── image31.png ├── image32.png ├── image33.png ├── image34.png ├── image35.png ├── image36.png ├── image37.png ├── image38.png ├── image39.png ├── image4.png ├── image40.png ├── image41.png ├── image42.png ├── image43.png ├── image44.png ├── image45.png ├── image46.png ├── image47.png ├── image48.png ├── image49.png ├── image5.png ├── image50.png ├── image51.png ├── image52.png ├── image53.png ├── image54.png ├── image55.png ├── image56.png ├── image57.png ├── image58.png ├── image59.png ├── image6.png ├── image60.png ├── image61.png ├── image62.png ├── image63.png ├── image64.png ├── image65.png ├── image66.png ├── image67.png ├── image68.png ├── image69.png ├── image7.png ├── image70.png ├── image71.png ├── image72.png ├── image73.png ├── image74.png ├── image75.png ├── image76.png ├── image77.png ├── image78.png ├── image79.png ├── image8.png ├── image80.png ├── image81.png ├── image82.png ├── image83.png ├── image84.png ├── image85.png ├── image86.png ├── image87.png ├── image88.png ├── image89.png ├── image9.png ├── image90.png ├── image91.png ├── image92.png ├── image93.png ├── image94.png ├── image95.png ├── image96.png ├── image97.png ├── image98.png ├── image99.png ├── image15-1.png ├── image-badge1.png ├── image-badge2.png ├── image-badge3.png ├── image-badge4.png ├── image-badge5.png ├── image-badge6.png ├── image-build1.png ├── image-commit1.png ├── image-contoso.png ├── image-tests1.png ├── image-tests2.png ├── image-release1.png ├── image-release2.png ├── image-release3.png └── image-githublogin.png └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | GitHub.to Global.docx 2 | GitHub+Azure.docx 3 | -------------------------------------------------------------------------------- /images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image1.png -------------------------------------------------------------------------------- /images/image10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image10.png -------------------------------------------------------------------------------- /images/image100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image100.png -------------------------------------------------------------------------------- /images/image101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image101.png -------------------------------------------------------------------------------- /images/image102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image102.png -------------------------------------------------------------------------------- /images/image103.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image103.png -------------------------------------------------------------------------------- /images/image104.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image104.png -------------------------------------------------------------------------------- /images/image105.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image105.png -------------------------------------------------------------------------------- /images/image106.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image106.png -------------------------------------------------------------------------------- /images/image11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image11.png -------------------------------------------------------------------------------- /images/image12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image12.png -------------------------------------------------------------------------------- /images/image13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image13.png -------------------------------------------------------------------------------- /images/image14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image14.png -------------------------------------------------------------------------------- /images/image15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image15.png -------------------------------------------------------------------------------- /images/image16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image16.png -------------------------------------------------------------------------------- /images/image17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image17.png -------------------------------------------------------------------------------- /images/image18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image18.png -------------------------------------------------------------------------------- /images/image19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image19.png -------------------------------------------------------------------------------- /images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image2.png -------------------------------------------------------------------------------- /images/image20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image20.png -------------------------------------------------------------------------------- /images/image21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image21.png -------------------------------------------------------------------------------- /images/image22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image22.png -------------------------------------------------------------------------------- /images/image23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image23.png -------------------------------------------------------------------------------- /images/image24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image24.png -------------------------------------------------------------------------------- /images/image25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image25.png -------------------------------------------------------------------------------- /images/image26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image26.png -------------------------------------------------------------------------------- /images/image27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image27.png -------------------------------------------------------------------------------- /images/image28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image28.png -------------------------------------------------------------------------------- /images/image29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image29.png -------------------------------------------------------------------------------- /images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image3.png -------------------------------------------------------------------------------- /images/image30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image30.png -------------------------------------------------------------------------------- /images/image31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image31.png -------------------------------------------------------------------------------- /images/image32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image32.png -------------------------------------------------------------------------------- /images/image33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image33.png -------------------------------------------------------------------------------- /images/image34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image34.png -------------------------------------------------------------------------------- /images/image35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image35.png -------------------------------------------------------------------------------- /images/image36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image36.png -------------------------------------------------------------------------------- /images/image37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image37.png -------------------------------------------------------------------------------- /images/image38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image38.png -------------------------------------------------------------------------------- /images/image39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image39.png -------------------------------------------------------------------------------- /images/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image4.png -------------------------------------------------------------------------------- /images/image40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image40.png -------------------------------------------------------------------------------- /images/image41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image41.png -------------------------------------------------------------------------------- /images/image42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image42.png -------------------------------------------------------------------------------- /images/image43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image43.png -------------------------------------------------------------------------------- /images/image44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image44.png -------------------------------------------------------------------------------- /images/image45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image45.png -------------------------------------------------------------------------------- /images/image46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image46.png -------------------------------------------------------------------------------- /images/image47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image47.png -------------------------------------------------------------------------------- /images/image48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image48.png -------------------------------------------------------------------------------- /images/image49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image49.png -------------------------------------------------------------------------------- /images/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image5.png -------------------------------------------------------------------------------- /images/image50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image50.png -------------------------------------------------------------------------------- /images/image51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image51.png -------------------------------------------------------------------------------- /images/image52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image52.png -------------------------------------------------------------------------------- /images/image53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image53.png -------------------------------------------------------------------------------- /images/image54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image54.png -------------------------------------------------------------------------------- /images/image55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image55.png -------------------------------------------------------------------------------- /images/image56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image56.png -------------------------------------------------------------------------------- /images/image57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image57.png -------------------------------------------------------------------------------- /images/image58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image58.png -------------------------------------------------------------------------------- /images/image59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image59.png -------------------------------------------------------------------------------- /images/image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image6.png -------------------------------------------------------------------------------- /images/image60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image60.png -------------------------------------------------------------------------------- /images/image61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image61.png -------------------------------------------------------------------------------- /images/image62.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image62.png -------------------------------------------------------------------------------- /images/image63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image63.png -------------------------------------------------------------------------------- /images/image64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image64.png -------------------------------------------------------------------------------- /images/image65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image65.png -------------------------------------------------------------------------------- /images/image66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image66.png -------------------------------------------------------------------------------- /images/image67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image67.png -------------------------------------------------------------------------------- /images/image68.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image68.png -------------------------------------------------------------------------------- /images/image69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image69.png -------------------------------------------------------------------------------- /images/image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image7.png -------------------------------------------------------------------------------- /images/image70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image70.png -------------------------------------------------------------------------------- /images/image71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image71.png -------------------------------------------------------------------------------- /images/image72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image72.png -------------------------------------------------------------------------------- /images/image73.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image73.png -------------------------------------------------------------------------------- /images/image74.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image74.png -------------------------------------------------------------------------------- /images/image75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image75.png -------------------------------------------------------------------------------- /images/image76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image76.png -------------------------------------------------------------------------------- /images/image77.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image77.png -------------------------------------------------------------------------------- /images/image78.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image78.png -------------------------------------------------------------------------------- /images/image79.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image79.png -------------------------------------------------------------------------------- /images/image8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image8.png -------------------------------------------------------------------------------- /images/image80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image80.png -------------------------------------------------------------------------------- /images/image81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image81.png -------------------------------------------------------------------------------- /images/image82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image82.png -------------------------------------------------------------------------------- /images/image83.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image83.png -------------------------------------------------------------------------------- /images/image84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image84.png -------------------------------------------------------------------------------- /images/image85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image85.png -------------------------------------------------------------------------------- /images/image86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image86.png -------------------------------------------------------------------------------- /images/image87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image87.png -------------------------------------------------------------------------------- /images/image88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image88.png -------------------------------------------------------------------------------- /images/image89.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image89.png -------------------------------------------------------------------------------- /images/image9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image9.png -------------------------------------------------------------------------------- /images/image90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image90.png -------------------------------------------------------------------------------- /images/image91.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image91.png -------------------------------------------------------------------------------- /images/image92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image92.png -------------------------------------------------------------------------------- /images/image93.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image93.png -------------------------------------------------------------------------------- /images/image94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image94.png -------------------------------------------------------------------------------- /images/image95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image95.png -------------------------------------------------------------------------------- /images/image96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image96.png -------------------------------------------------------------------------------- /images/image97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image97.png -------------------------------------------------------------------------------- /images/image98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image98.png -------------------------------------------------------------------------------- /images/image99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image99.png -------------------------------------------------------------------------------- /images/image15-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image15-1.png -------------------------------------------------------------------------------- /images/image-badge1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge1.png -------------------------------------------------------------------------------- /images/image-badge2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge2.png -------------------------------------------------------------------------------- /images/image-badge3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge3.png -------------------------------------------------------------------------------- /images/image-badge4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge4.png -------------------------------------------------------------------------------- /images/image-badge5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge5.png -------------------------------------------------------------------------------- /images/image-badge6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-badge6.png -------------------------------------------------------------------------------- /images/image-build1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-build1.png -------------------------------------------------------------------------------- /images/image-commit1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-commit1.png -------------------------------------------------------------------------------- /images/image-contoso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-contoso.png -------------------------------------------------------------------------------- /images/image-tests1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-tests1.png -------------------------------------------------------------------------------- /images/image-tests2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-tests2.png -------------------------------------------------------------------------------- /images/image-release1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-release1.png -------------------------------------------------------------------------------- /images/image-release2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-release2.png -------------------------------------------------------------------------------- /images/image-release3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-release3.png -------------------------------------------------------------------------------- /images/image-githublogin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsachinraj/GitHub-AzureDevOps/HEAD/images/image-githublogin.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | GitHub hosts over 100 million repositories containing applications of all 4 | shapes and sizes. But GitHub is just a start---those applications still 5 | need to get built, released, and managed to reach their full potential. 6 | 7 | [Azure Pipelines](https://azure.microsoft.com/services/devops/pipelines/) that 8 | enables you to continuously build, test, and deploy to any platform or 9 | cloud. It has cloud-hosted agents for Linux, macOS, and Windows; 10 | powerful workflows with native container support; and flexible 11 | deployments to Kubernetes, VMs, and serverless environments. 12 | 13 | Azure Pipelines provides unlimited CI/CD minutes and 10 parallel jobs to 14 | every GitHub open source project for free. All open source projects run 15 | on the same infrastructure that our paying customers use. That means 16 | you'll have the same fast performance and high quality of service. Many 17 | of the top open source projects are already using Azure Pipelines for 18 | CI/CD, such as Atom, CPython, Pipenv, Tox, Visual Studio Code, and 19 | TypeScript---and the list is growing every day. 20 | 21 | In addition to Azure Pipelines, GitHub users can also benefit from 22 | [Azure Boards](https://azure.microsoft.com/services/devops/boards/), a 23 | set of features that enable you to plan, track, and discuss work across 24 | your teams using Kanban boards, backlogs, team dashboards, and custom 25 | reporting. You can link GitHub activities from Azure Boards by 26 | mentioning them in commits and pull requests, and even automate the 27 | state transition of linked work items when pull requests are approved. 28 | 29 | In this demo, you'll see how easy it is to set up Azure Pipelines and 30 | Azure Boards with your GitHub projects and how you can start seeing 31 | benefits immediately. 32 | 33 | # Key Takeaways 34 | 35 | The key takeaways of the demo are: 36 | 37 | - Microsoft provides the only comprehensive DevOps solution that spans 38 | from development to project management to deployment to operations. 39 | 40 | - It doesn't matter what technologies of processes you're using---even 41 | setting up a Node.js solution on GitHub to deploy to a Linux 42 | container that connects to a Cosmos DB is a seamless, 43 | straightforward experience. 44 | 45 | - Azure offers a practical approach to automation at every step of the 46 | DevOps lifecycle that enables companies to focus their efforts on 47 | creating business value. 48 | 49 | 50 | 51 | ## Prerequisites: 52 | 53 | These items are required for this demo. 54 | 55 | 1. A GitHub account from . 56 | 57 | 2. An Azure account from . 58 | 59 | 3. An Azure DevOps account from 60 | 61 | > **Note:** If you are using your own machine, you will also need the following: 62 | 63 | 4. ARM Outputs extension installed in your Azure DevOps account from 64 | . 65 | 66 | 5. Git installed from . 67 | 68 | 6. Visual Studio Code installed from . 69 | 70 | 7. Azure Pipelines extension for Visual Studio Code installed from 71 | . 72 | 73 | 8. GitHub Pull Requests extension for Visual Studio Code installed from 74 | . 75 | 76 | 77 | ## Demo Setup 78 | 79 | You will need to perform these steps prior to presenting this demo/lab. 80 | 81 | - [] Login to the virtual machine. 82 | 83 | - [] Inside the virtual machine, open Edge and go to https://github.com/Microsoft/ContosoAir/ 84 | 85 | - [] We will fork this repo. Select **Fork** and select your account. You will be prompted to enter your credentials and enter the authentication code if you have 2FA enabled for your account 86 | 87 | Once the repo is forked, clone the GitHub repo locally and open it in Visual Studio Code. 88 | 89 | - [] Copy the URL from the address bar 90 | 91 | - [] Start Visual Studio Code. Press **Ctrl+Shift+P** to bring the Command Palette and enter **Git: Clone** to clone the Git repository. 92 | 93 | - [] You will be asked for the URL of the remote repository (this will be the URL of your forked repository). Paste the URL you copied earlier 94 | 95 | - [] Choose the directory under which to put the local repository 96 | 97 | - [] Choose **Open Repository** when prompted 98 | 99 | **Azure Subscription** 100 | 101 | >[!note] We will be publishing a node-based web app that has a Cosmos DB (Mongo DB) backend. You will need an Azure subscription. If you do not want to deploy to your subscription, you can use the Azure Pass provided for this technical workshop. See the **resources** tab for your Azure pass code. You will need to go to [https://www.microsoftazurepass.com](https://www.microsoftazurepass.com/) and redeem that code against any MSA. Then you would use the MSA to log into the Azure Portal. 102 | 103 | - [] Open a new tab and navigate to [https://dev.azure.com](https://dev.azure.com) to create a new Azure DevOps org/account. Select **Start for free**. Enter the same credentials you entered to login to Azure 104 | 105 | **OR** 106 | 107 | - [] You can use the [Azure DevOps Demo Generator](https://azuredevopsdemogenerator-staging.azurewebsites.net/?nameContosoAir-V1) to spin up a new project 108 | 109 | 110 | # Demo Scenario 111 | 112 | In this demo, we'll be illustrating the integration and automation benefits of Azure DevOps. We will take on the role of helping a 113 | fictitious airline---Contoso Air---that has developed their flagship web site using Node.js. To improve their operations, they want to implement 114 | pipelines for continuous integration and continuous delivery so that they can quickly update their public services and take advantage of the 115 | full benefits of DevOps and the cloud. 116 | 117 | The site will be hosted in Azure, and they want to automate the entire process so that they can spin up all the infrastructure needed to deploy 118 | and host the application without any manual intervention. Once this process is in place, it will free up their technology teams to focus 119 | more on generating business value. 120 | 121 | ## Exercise 1: Setting up automated CI/CD pipelines with Azure Pipelines 122 | 123 | In this demo, we will help Contoso Air revamp a critical component of their DevOps scenario. Like all airlines, they rely on their web site to generate and manage business opportunities. However, the current processes they have in place to move a change from their source code to their production systems is time-consuming and open to human error. They use GitHub to manage their source code and want to host their production site on Azure, so it will be our job to automate everything in the middle. 124 | 125 | This will involve setting up a pipeline so that commits to the GitHub 126 | repo invoke a continuous integration build in Azure DevOps. Once that build is complete, it will invoke a continuous delivery deployment to push the bits out to Azure, creating the required resources, if necessary. The first thing we need to do is to connect GitHub with Azure DevOps, which we can do via the Azure Pipelines 127 | extension in the GitHub Marketplace. 128 | 129 | 130 | # Task 1: Installing Azure Pipelines from GitHub Marketplace 131 | 132 | Azure Pipelines is available in GitHub Marketplace which makes it even more easy for teams to configure a CI/CD pipeline for any Azure application using your preferred language and framework as part of your GitHub workflow in just a few simple steps 133 | 134 | 1. Switch to the browser tab open to the root of your GitHub fork. 135 | 136 | 137 | 1. Navigate to the **GitHub Marketplace** 138 | 139 | ![](./images/image1.png) 140 | 141 | 142 | 1. Search for **"pipelines"** and click **Azure Pipelines**. 143 | 144 | ![](./images/image2.png) 145 | 146 | 147 | 148 | 1. Scroll to the bottom and click **Install it for free**. If you previously installed Azure Pipelines, select **Configure access** instead to skip steps 6-8. 149 | 150 | ![](./images/image3.png) 151 | 152 | >**Note:** Azure Pipelines is free to use for both public and private repos. You get unlimited build minutes and 10 free parallel jobs for public repositories. For private repos, you get 1 free parallel job and 1800 minutes per month. If you have a need to scale your builds, you can add parallel job support for a nominal fee. I 153 | 154 | 1. If you have multiple **GitHub** accounts, select the one you forked 155 | the project to from the **Switch billing account** dropdown. 156 | 157 | ![](./images/image4.png) 158 | 159 | 1. Click **Complete order and begin installation**. 160 | 161 | ![](./images/image5.png) 162 | 163 | 164 | ![](./images/image6.png) 165 | 166 | 1. Select the repositories you want to include (or **All 167 | repositories**) and click **Install**. 168 | 169 | >**Note:** If you've previously installed Azure Pipelines, you may 170 | need to toggle between the "All" and "Select" radio buttons to enable the 171 | wizard in Task 2. You can always create the pipeline directly from Azure 172 | Pipelines if the wizard does not appear. 173 | 174 | ![](./images/image7.png) 175 | 176 | 177 | # Task 2: Configuring an Continuous Integration Pipeline 178 | 179 | Now that Azure Pipelines has been installed and configured, we can start building the pipelines but we will need to select a project where the pipeline will be saved. You may select an existing or create a new Azure DevOps project to hold and run the pipelines we need for continuous integration and continuous delivery. The first thing we'll do is to create a CI pipeline. 180 | 181 | 1. Select the organization and Azure DevOps project that you want to use. If you do not have one, you can create for free. 182 | 183 | ![](./images/image8.png) 184 | 185 | 1. Select the forked repo. 186 | 187 | ![](./images/image9.png) 188 | 189 | Every build pipeline is simply a set of tasks. Whether it's copying files, compiling source, or publishing artifacts, the existing library of tasks covers the vast majority of scenarios. You can even create your own if you have specialized needs not already covered. We're going to use YAML, a markup syntax that lends itself well to describing the build pipeline. Note that the Node.js pipeline as a starting point based on an analysis of our source project. We'll replace the contents with the final YAML required for our project. 190 | 191 | 1. Select the recommended template. 192 | 193 | ![](./images/image10.png) 194 | 195 | 1. Replace the default template with the YAML below. To make it easy to copy and paste the code, we have saved this in a file named **firstpipeline.yml** in the desktop folder inside the VM. Double click the file to open it in VS Code. 196 | 197 | >[!note] YAML is very strict with indentation. If you are new to YAML, I would recommend that you use tools to format and validate the code. There are several free tools available on the web. 198 | 199 | ````yaml-nocopy 200 | pool: 201 | vmImage: 'ubuntu-16.04' 202 | 203 | trigger: 204 | - master 205 | 206 | steps: 207 | - task: CopyFiles@2 208 | displayName: 'Copy Files to: $(build.artifactstagingdirectory)/Templates' 209 | inputs: 210 | SourceFolder: deployment 211 | Contents: '*.json' 212 | TargetFolder: '$(build.artifactstagingdirectory)/Templates' 213 | 214 | - task: Npm@1 215 | displayName: 'npm custom' 216 | inputs: 217 | command: custom 218 | verbose: false 219 | customCommand: 'install --production' 220 | 221 | - task: ArchiveFiles@2 222 | displayName: 'Archive $(Build.SourcesDirectory)' 223 | inputs: 224 | rootFolderOrFile: '$(Build.SourcesDirectory)' 225 | includeRootFolder: false 226 | 227 | - task: PublishBuildArtifacts@1 228 | displayName: 'Publish Artifact: drop' 229 | ```` 230 | 231 | 1. Click **Save and run**. 232 | 233 | ![](./images/image11.png) 234 | 235 | 1. Confirm the **Save and run** to commit the YAML definition directly 236 | to the master branch of the repo. 237 | 238 | ![](./images/image12.png) 239 | 240 | 1. Follow the build through to completion. 241 | 242 | ![](./images/image-build1.png) 243 | 244 | 245 | 246 | # Task 3: Adding a build status badge 247 | 248 | An important sign for a quality project is its build status badge. When someone finds a project that has a badge indicating that the project is currently in a successful build state, it's a sign that the project is maintained effectively. 249 | 250 | 1. Click the build pipeline to navigate to its overview page. 251 | 252 | ![](./images/image-badge6.png) 253 | 254 | 1. From the **ellipses** dropdown, select **Status badge**. 255 | 256 | ![](./images/image-badge1.png) 257 | 258 | 259 | 1. The **Status badge** UI provides a quick and easy way to integrate the build status wherever you want. Often, you'll want to use the provided URLs in your own dashboards, or you can use the Markdown snippet to add the status badge to locations such as Wiki pages. Click the **Copy to clipboard** button for **Sample Markdown**. 260 | 261 | ![](./images/image-badge2.png) 262 | 263 | 264 | 1. Return to Visual Studio Code and open the **README.md** file. 265 | 266 | 1. Paste in the clipboard contents at the beginning of the file. 267 | 268 | ![](./images/image-badge3.png) 269 | 270 | 1. Presss **Ctrl+S** to save the file. 271 | 272 | 1. From the **Source Control** tab, enter a commit message like **Added build status badge** and press **Ctrl+Enter** to commit. Confirm if prompted. 273 | 274 | ![](./images/image-badge4.png) 275 | 276 | 1. In Git, only changes need to be staged first to be included in the commit. If you are prompted to choose whether you want VS Code automatically to stage all changes and commit them directly, choose **Always** 277 | 278 | ![](./images/image-commit1.png) 279 | 280 | 1. If you receive an error prompting you to configure user .name and user.email in git, open a command prompt and enter the following command to set your user name and email address: 281 | 282 | > ++git config --global user.name "Your Name"++ 283 | 284 | > ++git config --global user.email "Your Email Address"++ 285 | 286 | 1. Press the **Synchronize Changes** button at the bottom of the window to push the commit to the server. Confirm if prompted. 287 | 288 | ![](./images/image44.png) 289 | 290 | 1. You will need to sign in to GitHub, if you have not already signed in 291 | 292 | ![](./images/image-githublogin.png) 293 | 294 | 295 | 1. Go to the readme file on the browser and you will see the status. **It's that easy :)** 296 | 297 | ![](./images/image-badge5.png) 298 | 299 | 300 | # Task 4: Embeding automated tests in the CI pipeline 301 | 302 | Now that we have our CI successfully built, it's time to deploy but how do we know if the build is a good candidate for release? Most teams run automated tests, such as unit tests, as a part of their CI process to ensure that they are releasing a high-quality software. Teams capture key code metrics such as code coverage, code anylaysis, as they run the tests, to make sure that the code quality does not drop and the technical debt if not completely eliminated, is kept low. 303 | 304 | We're going to pull down the azure-pipelines.yml file that we created earlier and add tasks to run some tests and publish the test results. 305 | 306 | 1. Return to Visual Studio Code. 307 | 308 | 1. From the **Explorer** tab, open **azure-pipelines.yml**. 309 | 310 | ![](./images/image42.png) 311 | 312 | Before we make our change, let's take a quick look at the build tasks. There are four steps required for the build. First, deployment templates are copied to a target folder for use during the release process. Next, the project is built with NPM. 313 | After that, the built solution is archived and finally published for the release pipeline to access. With the Azure Pipelines extension 314 | for Visual Studio Code, you get a great YAML editing experience, including support for IntelliSense. 315 | 316 | What we are missing is testing in the pipeline. We already have unit tests for our code. We just have to run them in the pipeline. We will add tasks to run the test and publish the results and code coverage. 317 | 318 | 1. We will remove all the steps and replace it with the following code. You can copy and paste the code from **SecondPipeline.yml** file from the desktop inside the VM. 319 | 320 | ````yaml-nocopy 321 | pool: 322 | vmImage: 'ubuntu-16.04' 323 | 324 | trigger: 325 | - master 326 | 327 | steps: 328 | - task: Npm@1 329 | inputs: 330 | command: 'install' 331 | - script: 332 | npm test 333 | displayName: 'Run unit tests' 334 | continueOnError: true 335 | 336 | - task: PublishTestResults@2 337 | displayName: 'Publish Test Results' 338 | condition: succeededOrFailed() 339 | inputs: 340 | testResultsFiles: '$(System.DefaultWorkingDirectory)/test-report.xml' 341 | 342 | - task: PublishCodeCoverageResults@1 343 | displayName: 'Publish Code Coverage' 344 | condition: in(variables['Agent.JobStatus'], 'Succeeded') 345 | inputs: 346 | codeCoverageTool: Cobertura 347 | summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/*coverage.xml' 348 | reportDirectory: '$(System.DefaultWorkingDirectory)/coverage' 349 | 350 | - task: ArchiveFiles@2 351 | displayName: 'Archive sources' 352 | inputs: 353 | rootFolderOrFile: '$(Build.SourcesDirectory)' 354 | includeRootFolder: false 355 | 356 | - task: CopyFiles@2 357 | displayName: 'Copy ARM templates' 358 | inputs: 359 | SourceFolder: deployment 360 | Contents: '*.json' 361 | TargetFolder: '$(build.artifactstagingdirectory)/Templates' 362 | 363 | - task: PublishBuildArtifacts@1 364 | displayName: 'Publish Artifact: drop' 365 | 366 | ```` 367 | 368 | 1. Press **Ctrl+S** to save the file. 369 | 370 | 1. From the **Source Control** tab, enter a commit message like **Updated build pipeline** and press **Ctrl+Enter** to commit. 371 | Confirm if prompted. 372 | 373 | ![](./images/image43.png) 374 | 375 | 1. Press the **Synchronize Changes** button at the bottom of the window to push the commit to the server. Confirm if prompted. 376 | 377 | ![](./images/image44.png) 378 | 379 | 380 | 1. Back in Azure DevOps, we can see that our build pipeline has kicked off a new build. We can follow as it executes the tasks we defined earlier, and even get a real-time view into what's going on at each step. When the build completes, we can review the logs and any tests that were performed as part of the process. 381 | 382 | 1. Track the build tasks. 383 | 384 | ![](./images/image47.png) 385 | 386 | 1. Follow the build through to completion. 387 | 388 | ![](./images/image48.png) 389 | 390 | 1. Now that the build has completed, let's check out the **Tests** tab to view the published tests results. We can get quantitative metrics such as total test count, test pass percentage, failed test cases, etc., from the **Summary** section 391 | 392 | ![](./images/image-tests1.png) 393 | 394 | 1. The **Results** section lists all tests executed and reported as part of the current build or release. The default view shows only the failed and aborted tests in order to focus on tests that require attention. However, you can choose other outcomes using the filters provided 395 | 396 | ![](./images/image-tests2.png) 397 | 398 | 1. Finally, you can use the details pane to view additional information, for the selected test case, that can help troubleshooting such as the error message, stack trace, attachments, work items, historical trend, and more. 399 | 400 | From the results, we can see all 40 tests have passed which means we have not broken any changes and this build is a good candidate for deployment. 401 | 402 | 403 | ## Task 5: Configuring a CD pipeline with Azure Pipelines 404 | 405 | Now that the build pipeline is complete and all tests have passed, we can turn our attention to creating a release pipeline. 406 | 407 | Like the build templates, there are many packaged options available that cover common deployment scenarios, such as publishing to Azure. But to illustrate how flexible and productive the experience is, we will build this pipeline from an empty template. 408 | 409 | 1. From the build summary page, click **Release** to create a new CD pipeline to deploy the artifacts produced by the build. 410 | 411 | ![](./images/image13.png) 412 | 413 | 1. Click **Empty job**. 414 | 415 | ![](./images/image14.png) 416 | 417 | The first item to define in a release pipeline is exactly what will be released and when. In our case, it's the output 418 | generated from the build pipeline. Note that we could also assign a 419 | schedule, such as if we wanted to release the latest build every 420 | night. 421 | 422 | 1. Select the associated artifact. 423 | 424 | ![](./images/image15-1.png) 425 | 426 | 1. Set **Source** to the build pipeline created earlier and **Default 427 | version** to **Latest**. Change the **Source alias**, if you want, to something like **"\_ContosoAir-CI"** and click **Add**. Note that this is an identifier (typically a short name) that uniquely identifies an artifact linked to the release pipeline. It cannot contain the characters: \ / : * ? < > | or double quotes 428 | 429 | ![](./images/image16.png) 430 | 431 | As we did with continuous integration starting on a source commit, we also want to have this pipeline automatically start when the build pipeline completes. It's just as easy. 432 | 433 | 1. Click the **Triggers** button on the artifact. 434 | 435 | ![](./images/image17.png) 436 | 437 | 1. **Enable** continuous integration, if it is not already enabled. 438 | 439 | ![](./images/image18.png) 440 | 441 | >We also have the option of adding quality gates to the release process. For example, we could require that a specific user or group approve a release before it continues, or that they approve it after it's been deployed. These gates provide notifications to the necessary groups, as well as polling support if you're automating the gates using something dynamic, such as an Azure function, REST API, work item query, and more. We won't add any of that here, but we could easily come back and do it later on. 442 | 443 | 1. Click the **pre-deployment conditions** button. 444 | 445 | ![](./images/image19.png) 446 | 447 | 1. Review pre-deployment condition options. 448 | 449 | ![](./images/image20.png) 450 | 451 | In this pipeline, we're going to need to specify the same resource group in multiple tasks, so it's a good practice to use a pipeline variable. We'll add one here for the new Azure resource group we want to provision our resources to. Note that 452 | there are also a variety of deployment options we can configure, as well as a retention policy. 453 | 454 | 1. Select the **Variables** tab. 455 | 456 | ![](./images/image21.png) 457 | 458 | 1. **Add** a ++resourcegroup++ variable that is not currently used by 459 | an existing resource group in your Azure account (**"contosoair"** 460 | will be used in this script). 461 | 462 | ![](./images/image22.png) 463 | 464 | Also, just like the build pipeline, the release pipeline is really just a set of tasks. There are many out-of-the-box tasks available, and you can build your own if needed. The first task our release requires is to set up the Azure deployment environment if it doesn't yet exist. After we add the task, I can authorize access to the Azure account I want to deploy 465 | to and instruct it to use the variable name we just specified for the resource group name. 466 | 467 | 1. Select the **Tasks** tab. 468 | 469 | ![](./images/image23.png) 470 | 471 | 1. Click the **Add task** button. 472 | 473 | ![](./images/image24.png) 474 | 475 | 1. Search for **"resource"** and **Add** an **Azure Resource Group 476 | Deployment** task. 477 | 478 | ![](./images/image25.png) 479 | 480 | 1. Select the newly created task. 481 | 482 | ![](./images/image26.png) 483 | 484 | 1. Select and authorize an Azure subscription. Note you will need to disable popup-blockers to sign in to Azure for authorization. If the pop-up window hangs, please close and try it again. 485 | 486 | ![](./images/image27.png) 487 | 488 | 1. Set the **Resource group** to **"\$(resourcegroup)"** and select a 489 | **Location**. 490 | 491 | ![](./images/image28.png) 492 | 493 | Rather than having to manually create the Azure 494 | resources required to host the web app, the team has defined an 495 | Azure Resource Manager---or ARM---template that describes the 496 | environment in JSON. This allows the environment definition to be 497 | updated and managed like any other source file. These were the files 498 | we copied to the Templates folder during the build pipeline. You can 499 | also override the template parameters as part of this configuration, 500 | which we'll do here using my name. 501 | 502 | 1. Enter the settings below. You can use the browse navigation to 503 | select them from the most recent build output. 504 | 505 | ![](./images/image-release3.png) 506 | 507 | Template: 508 | **\$(System.DefaultWorkingDirectory)/\_ContosoAir-CI/drop/Templates/azuredeploy.json** 509 | Template parameters: 510 | **\$(System.DefaultWorkingDirectory)/\_ContosoAir-CI/drop/Templates/azuredeploy.parameters.json** 511 | 512 | You will also need to set **Override template parameters** to 513 | generate an Azure app service name that is globally unique, so your 514 | name is recommended. For example, if your name is **John Doe**, use 515 | something like ++**-p\_environment johndoe**++. This will be used as 516 | part of the app service name in Azure, so please limit it to 517 | supported characters. 518 | 519 | ![](./images/image29.png) 520 | 521 | When this task completes, it will have generated 522 | an Azure resource group with the resources required to run our 523 | application. However, the ARM template does some processing of the 524 | variables to generate names for the resources based on the input 525 | variables, which we will want to use in future tasks. While we could 526 | potentially hardcode those variables, it could introduce problems if 527 | changes are made in the future, so we'll use the ARM Outputs task to 528 | retrieve those values and put them into pipeline variables for us to 529 | use. This task happens to be a 3^rd^ party task I installed earlier 530 | from the Visual Studio Marketplace. It contains this and many other 531 | extensions for Azure DevOps from both Microsoft and 3^rd^ parties. 532 | 533 | 1. Click the **Add task** button. 534 | 535 | ![](./images/image24.png) 536 | 537 | 1. Search for **"arm"** and select **Learn more \| More information**. 538 | This will open the GitHub project for this extension in a new tab. 539 | 540 | ![](./images/image30.png) 541 | 542 | 1. Click the link to the Visual Studio Marketplace. 543 | 544 | ![](./images/image31.png) 545 | 546 | 1. Close the new tab. 547 | 548 | ![](./images/image32.png) 549 | 550 | Now let's get back to adding the ARM Outputs 551 | task. The key variable we care about here is the name of the app 552 | service created, which our ARM template has specified as an output. 553 | This task will populate it for us to use as the "web" variable in 554 | the next task. 555 | 556 | 1. **Add** an **ARM Outputs** task. 557 | 558 | ![](./images/image33.png) 559 | 560 | 1. Select the newly created task. 561 | 562 | ![](./images/image34.png) 563 | 564 | 1. Select the same subscription from the previous task and enter the 565 | same resource group variable name. 566 | 567 | ![](./images/image35.png) 568 | 569 | Finally, we can deploy the app service. We'll use 570 | the same subscription as earlier and specify the web variable as the 571 | name of the app service we want to deploy to. By this time in the 572 | pipeline, it will have been filled in for us by the ARM Outputs 573 | task. Also note that we have the option to specify a slot to deploy 574 | to, but that is not covered in this demo. 575 | 576 | 1. Click the **Add task** button. 577 | 578 | ![](./images/image24.png) 579 | 580 | 1. Search for **"app service"** and **Add** an **Azure App Service 581 | Deploy** task. 582 | 583 | ![](./images/image36.png) 584 | 585 | 1. Select the newly created task. 586 | 587 | ![](./images/image37.png) 588 | 589 | 1. Select the same subscription as earlier. 590 | 591 | ![](./images/image38.png) 592 | 593 | 1. Enter the **App Service name** of **"\$(web)"**. 594 | 595 | ![](./images/image39.png) 596 | 597 | 1. **Save** the pipeline. 598 | 599 | ![](./images/image40.png) 600 | 601 | 1. Select **+ Release** and then select **Create a Release** 602 | 603 | ![](./images/image-release1.png) 604 | 605 | 1. Select **Create** to start a new release. 606 | 607 | 1. Click **In progress** to follow the release process. 608 | 609 | ![](./images/image51.png) 610 | 611 | 1. Note that it will take a few minutes (around 5 at the time of drafting) for the app to finish deploying due to heavy first-time operations. Move ahead to the next step while it works in the backgroud. 612 | 613 | ![](./images/image52.png) 614 | 615 | 1. Select the **App Service Deploy** task to view the detailed log. You should find the URL to the published website here. Ctrl+Click the link to open it in a separate tab. 616 | 617 | ![](./images/image-release2.png) 618 | 619 | 1. This should open the web page of the Conotoso Air: 620 | 621 | ![](./images/image-contoso.png) 622 | 623 | 624 | 625 | # Exercise 2 -- Managing GitHub Projects with Azure DevOps 626 | 627 | DevOps is not just about automation; while continuous integartion and continuous delivery are key practices, teams also need continuous planning. As the saying software developmement is a team sport - it is vital that everyone stays on the same page. While GitHub issues help teams manage work artifacts such as issues and bugs which might be sufficient for inidviduals and small teams, but they do not scale well to support the needs of enterprise teams. 628 | 629 | Azure Boards provides a wealth of project management functionality that spans Kanban boards, backlogs, team dashboards, and 630 | custom reporting. By connecting Azure Boards with GitHub repositories, teams can take advantage of the rich project management capabilities. You can create links between GitHub commits and pull requests to work items tracked in Azure Boards. This enables a seamless way for you to use GitHub for software development while using Azure Boards to plan and track your work. 631 | 632 | 633 | 634 | # Task 1: Connecting GitHub with Azure Boards 635 | 636 | 637 | 1. Return to the web app tab and click **Login**. 638 | 639 | ![](./images/image85.png) 640 | 641 | 642 | 643 | 1. Log in with any email and password. 644 | 645 | ![](./images/image86.png) 646 | 647 | 648 | 1. Click **Book**. 649 | 650 | ![](./images/image87.png) 651 | 652 | 653 | 1. Expand the airport dropdown to note that it's not sorted 654 | alphabetically by city. 655 | 656 | ![](./images/image88.png) 657 | 658 | In our scenario, users will need to be able to book flights by selecting the cities involved. We will create a new 659 | user story to sort the airports listed in the booking form in alphabetical order by city. Ordinarily we would create the user 660 | story at a higher level and add tasks to define how the story is to be implemented, but for our demo purposes here we'll leave it as 661 | a single work item. 662 | 663 | 1. Return to the Azure DevOps tab. 664 | 665 | 1. Navigate to **Boards \| Backlogs**. 666 | 667 | ![](./images/image76.png) 668 | 669 | 670 | 671 | 1. Click **New Work Item** and add a user story with the title **As a customer, I want to see airports sorted by city**. Press **Enter** to create. 672 | 673 | ![](./images/image77.png) 674 | 675 | In addition to working with work items in a backlog, we have a very flexible Kanban board option. With the 676 | board, we can edit items on a card in line, or even drag cards around to change their state and assignment. Let's take ownership of 677 | the new user story so we can begin work. 678 | 679 | 1. Click **View as board**. 680 | 681 | ![](./images/image78.png) 682 | 683 | 1. Drag the newly created user story to the **Active** column. 684 | 685 | ![](./images/image79.png) 686 | 687 | 1. Dropping the user story onto the **Active** column assigns it to you 688 | and sets its **State** to **Active**. Make note of the task ID for 689 | reference later during a future commit and pull request. 690 | 691 | ![](./images/image80.png) 692 | 693 | In order to complete our integration, we'll need to wire up a connection between this project and the GitHub repo. 694 | 695 | 696 | 697 | # Task 2: Connecting GitHub Repo to Azure Boards 698 | 699 | 1. Click **Project settings**. 700 | 701 | ![](./images/image81.png) 702 | 703 | 1. Under **Boards**, select **GitHub connections**. 704 | 705 | ![](./images/image82.png) 706 | 707 | 1. Click **Connect your GitHub account**. 708 | 709 | ![](./images/image83.png) 710 | 711 | 1. Select the project repo and click **Save**. 712 | 713 | ![](./images/image84.png) 714 | 715 | Let's take a look at our deployed site to see 716 | what the current booking experience is like. As you can see, the 717 | airports appear to be sorted by airport code, which isn't the 718 | behavior we want our users to see. 719 | 720 | 721 | 722 | 723 | # Task 3: Committing to Complete a Task 724 | 725 | 726 | 1. Return to **Visual Studio Code**. 727 | 728 | We'll start off by creating a new branch for this 729 | task. The work itself is pretty straightforward. We just need to 730 | locate the place where airports are provided to the user experience 731 | and make sure they're being sorted by city name. 732 | 733 | 2. Click the **master** branch at the bottom of the window. 734 | 735 | ![](./images/image89.png) 736 | 737 | 738 | 3. From the top of the screen, click **Create new branch**. 739 | 740 | ![](./images/image90.png) 741 | 742 | 743 | 4. Enter the name **"airport-sorting"** and press **Enter**. This will 744 | activate the new branch. 745 | 746 | ![](./images/image91.png) 747 | 748 | 749 | 5. From the **Explorer** tab, open 750 | **src/services/airports.service.js**. 751 | 752 | ![](./images/image92.png) 753 | 754 | 755 | 6. Locate the **getAll** function and replace the existing code 756 | with the code below. This will sort the 757 | airports by city. 758 | 759 | ````JavaScript-nocopy 760 | 761 | getAll(){ 762 | return this._airports.filter(a > a.code).map(avoidEmptyCity).sort((a, b) > (a.city > b.city) ? 1 : -1); 763 | } 764 | 765 | ```` 766 | 767 | ![](./images/image93.png) 768 | 769 | 770 | 7. Press **Ctrl+S** to save the file. 771 | 772 | We'll commit it using a comment that includes special syntax to link it to the Azure Boards task we saw earlier. Now this commit will become trackable from project management, as 773 | long as we include the phrase "Fixes AB\#ID". 774 | 775 | 8. Switch to the **Source Control** tab and enter a commit message of 776 | **"Changes airport sorting. Fixes AB\#3464."**, but replace **3464** 777 | with the actual ID of the Azure Boards task. Press **Ctrl+Enter** 778 | and confirm the commit if prompted. 779 | 780 | ![](./images/image94.png) 781 | 782 | 783 | 9. Click the **Publish Changes** button at the bottom of the screen. 784 | 785 | ![](./images/image95.png) 786 | 787 | 788 | 10. When the push has completed, return to the GitHub browser tab. 789 | 790 | With the commit pushed, we'll create a pull 791 | request to drive those changes back into the master branch. In this 792 | case we're inheriting the title from the commit, but having the pull 793 | request mention "Fixes AB\#ID" will link and complete the target 794 | work item when the pull request is merged. 795 | 796 | 11. Click **Compare & pull request**, which should appear on its own. If 797 | not, refresh. 798 | 799 | ![](./images/image96.png) 800 | 801 | 802 | 12. Change the **base fork** to point at your project. By default it 803 | points at the original Microsoft repo, so be sure to change it. 804 | 805 | ![](./images/image97.png) 806 | 807 | 808 | 13. The title should initialize to the commit message entered earlier. 809 | Click **Create pull request**. 810 | 811 | ![](./images/image98.png) 812 | 813 | 814 | 14. Return to Visual Studio Code. 815 | 816 | Now we'll switch to the other side of the pull 817 | request and take on the role of reviewer. We can use Visual Studio 818 | Code to check out the pull request, analyze changes, and comment. 819 | Assuming we trust the fix, we can merge the pull request to update 820 | master and kick off the CI/CD. 821 | 822 | 15. Under **GitHub Pull Requests \| All**, right-click the pull request 823 | and select **Checkout Pull Request**. 824 | 825 | ![](./images/image99.png) 826 | 827 | 828 | 16. Expand the **Changes in Pull Request** tree. 829 | 830 | ![](./images/image100.png) 831 | 832 | 833 | 17. Select the **Description** from under the original pull request. 834 | 835 | ![](./images/image101.png) 836 | 837 | 838 | 18. Review the details of the pull request. 839 | 840 | ![](./images/image102.png) 841 | 842 | 843 | 19. Click **Merge pull request** and confirm the merge. 844 | 845 | ![](./images/image103.png) 846 | 847 | 848 | Once the deployment works its way through build 849 | and release, we can confirm the new functionality. 850 | 851 | 1. Follow the CI/CD pipeline through to completion. 852 | 853 | 1. Refresh the web app site. Return to the booking page (you'll need to 854 | log in again) and confirm the airports are sorted by city now 855 | (scroll down past the airports with no city name). 856 | 857 | ![](./images/image104.png) 858 | 859 | 1. Return to the Azure DevOps tab open to the Kanban board. 860 | 861 | Since the user story we were working on was 862 | linked in a pull request that was approved, Azure DevOps will 863 | automatically transition the state of the work item to "Closed". You 864 | can also see that the related GitHub commits and pull request were 865 | linked to the work item. 866 | 867 | 1. The user story should have already moved to the **Closed** state and 868 | column. Click to open it. 869 | 870 | ![](./images/image105.png) 871 | 872 | 873 | 1. The commit and pull request should now be visible under 874 | **Development**. 875 | 876 | ![](./images/image106.png) 877 | 878 | Summary 879 | 880 | 881 | Many organizations have their projects hosted in GitHub, and we just 882 | showed how you can set up automated deployment to Azure in minutes. And 883 | it doesn't matter what kind of application they're building or what kind 884 | of environment they're deploying to. Once this automation is in place, 885 | companies can turn their focus to developing business value instead of 886 | infrastructure. 887 | --------------------------------------------------------------------------------