DevOps Starter makes it easy to get started on Azure using either GitHub actions or Azure DevOps
Run the updated app locally
BASH
1$ cd Application 2 3$ npm install haddley-factorial-cc 4# or 5$ npm install haddley-factorial-js 6 7$ npm install 8$ npm run start
Run the unit tests locally
BASH
1$ cd ../Tests 2$ npm install 3$ gulp unittest
Run the functional tests locally
BASH
1$ xattr -d com.apple.quarantine chromedriver 2 3$ npm run start& 4$ cd ../Tests 5$ gulp functionaltest --webAppUrl http://localhost:3000/
Test factorial API in production
devops-starter-workflow.yaml
YAML
1name: Build and Deploy node Express app to azure 2on: 3 push: 4 branches: 5 - master 6 7env: 8 AZURE_WEBAPP_NAME: "haddley-factorial-api" # set this to your application's name 9 AZURE_WEBAPP_PACKAGE_PATH: "Application" # set this to the path to your web app project, defaults to the repository root 10 NODE_VERSION: '8.11.1' # set this to the node version to use 11 RESOURCEGROUPNAME: "haddley-factorial-api-rg" 12 LOCATION: "South Central US" 13 HOSTINGPLANNAME: "haddley-factorial-api-plan" 14 APPINSIGHTLOCATION: "South Central US" 15 SKU: "F1 Free" 16 17jobs: 18 build: 19 name: Build and Run tests 20 runs-on: ubuntu-latest 21 steps: 22 - uses: actions/checkout@v2 23 24 - name: Use Node.js ${{ env.NODE_VERSION }} 25 uses: actions/setup-node@v1 26 with: 27 node-version: ${{ env.NODE_VERSION }} 28 29 - name: npm install and build 30 continue-on-error: false 31 run: | 32 cd Application 33 npm install 34 npm run build --if-present 35 36 - name: Run unit tests 37 continue-on-error: false 38 run: | 39 cd Tests 40 npm install 41 gulp unittest 42 43 - name: Creating artifact directories 44 run: | 45 mkdir buildartifacts 46 mkdir deploymenttemplates 47 48 # Archive build artifact 49 - name: Archive Application 50 run: | 51 zip -qq -r ./buildartifacts/Application.zip ./Application 52 53 # Uploading application to build artifact 54 - name: Upload Application to Build Artifact 55 continue-on-error: false 56 uses: actions/upload-artifact@v2 57 with: 58 name: buildartifacts 59 path: buildartifacts 60 61 # Archive Arm templates 62 - name: Archive ArmTemplates 63 uses: montudor/action-zip@v0.1.0 64 with: 65 args: zip -qq -r ./deploymenttemplates/armtemplates.zip ./armTemplates 66 67 # Uploading Arm Templates to artifacts 68 - name: Upload Arm templates to Artifact 69 continue-on-error: false 70 uses: actions/upload-artifact@v2 71 with: 72 name: deploymenttemplates 73 path: deploymenttemplates 74 75 Deploy: 76 name: Deploy to azure web app 77 needs: build 78 runs-on: ubuntu-latest 79 steps: 80 # Downloading build artifact 81 - name: Download a Build Artifact 82 uses: actions/download-artifact@v2 83 continue-on-error: false 84 with: 85 name: buildartifacts 86 path: buildartifacts 87 88 # Uzipping build artifacts 89 - name: unzipping build artifact 90 run: | 91 unzip -qq ./buildartifacts/Application.zip -d . 92 93 # Downloading Arm Templates 94 - name: Download an Arm template 95 uses: actions/download-artifact@v2 96 continue-on-error: false 97 with: 98 name: deploymenttemplates 99 path: deploymenttemplates 100 101 # Uzipping Arm template directory 102 - name: unzipping arm artifact 103 run: | 104 unzip -qq ./deploymenttemplates/armtemplates.zip -d . 105 106 # Login to azure 107 - name: Login to Azure 108 uses: azure/login@v1 109 continue-on-error: false 110 with: 111 creds: ${{ secrets.AZURE_CREDENTIALS }} 112 113 # Deploy Arm template 114 - name: Deploy ARM Template 115 uses: azure/CLI@v1 116 continue-on-error: false 117 with: 118 inlineScript: | 119 az group create --name "${{ env.RESOURCEGROUPNAME }}" --location "${{ env.LOCATION }}" 120 az deployment group create --resource-group "${{ env.RESOURCEGROUPNAME }}" --template-file ./armTemplates/windows-webapp-template.json --parameters webAppName="${{ env.AZURE_WEBAPP_NAME }}" hostingPlanName="${{ env.HOSTINGPLANNAME }}" appInsightsLocation="${{ env.APPINSIGHTLOCATION }}" sku="${{ env.SKU }}" 121 122 # Deploy web app on azure 123 - name: 'Deploy to Azure WebApp' 124 uses: azure/webapps-deploy@v2 125 with: 126 app-name: ${{ env.AZURE_WEBAPP_NAME }} 127 package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} 128 129 # Job to run functional tests 130 FunctionalTests: 131 name: Run Functional tests 132 runs-on: windows-latest 133 needs: Deploy 134 steps: 135 - uses: actions/checkout@v2 136 137 - name: Use Node.js ${{ env.NODE_VERSION }} 138 uses: actions/setup-node@v1 139 with: 140 node-version: ${{ env.NODE_VERSION }} 141 142 # Run functional tests 143 - name: Run Functional Tests 144 continue-on-error: false 145 run: | 146 cd Application 147 npm install 148 cd ../Tests 149 npm install 150 gulp functionaltest --webAppUrl https://${{ env.AZURE_WEBAPP_NAME }}.azurewebsites.net/
routesindex.js
JAVASCRIPT
1'use strict'; 2var express = require('express'); 3var router = express.Router(); 4// var factorial = require('haddley-factorial-cc'); 5var factorial = require('haddley-factorial-js'); 6 7/* GET home page. */ 8router.get('/', function (req, res) { 9 res.render('index', { title: 'Express' }); 10}); 11 12router.get('/factorial/:n', (request, response) => { 13 try { 14 const n = Number(request.params.n); 15 const result = factorial.factorial_it(n); 16 response.json(result); 17 } 18 catch (err) { 19 response.status(500).send(err); 20 } 21}); 22 23module.exports = router;
unittestssampleUnitTests.js
JAVASCRIPT
1var assert = require('assert'); 2var app = require('../../Application/app'); 3var http = require('http'); 4 5describe('sampleUnitTests', function () { 6 before(function () { 7 }); 8 9 after(function () { 10 app.close(); 11 }); 12 13 it('Should return 200', function (done) { 14 http.get('http://localhost:3000', function (res) { 15 assert.equal(200, res.statusCode, 'Result code should be 200.'); 16 done(); 17 }); 18 }); 19 20 it('Assert title', function (done) { 21 http.get('http://localhost:3000', function (res) { 22 assert.equal(200, res.statusCode, 'Result code should be 200.'); 23 var data = ''; 24 25 res.on('data', function (chunk) { 26 data += chunk; 27 }); 28 29 res.on('end', function () { 30 assert.equal(true, data.includes('<title>Express - Node.js Express Application</title>'), 'Title should be Express - Node.js Express Application.'); 31 done(); 32 }) 33 }); 34 }); 35 36 37 it('Assert factorial 9', function (done) { 38 http.get('http://localhost:3000/factorial/9', function (res) { 39 assert.equal(200, res.statusCode, 'Result code should be 200.'); 40 var data = ''; 41 42 res.on('data', function (chunk) { 43 data += chunk; 44 }); 45 46 res.on('end', function () { 47 assert.equal(true, data.includes('362880')); 48 done(); 49 }) 50 }); 51 }); 52 53});





















